]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/gTopLevel/xmlDiff.ml
- the mathql interpreter is not helm-dependent any more
[helm.git] / helm / gTopLevel / xmlDiff.ml
index 3d9bb39ac87f4c3bb09ce8343b7b18ecf2820628..307e02ac0db8c325fd45b0b5ebb3158a89118a3c 100644 (file)
 let myprerr_endline = prerr_endline;;
 let prerr_endline _ = ();;
 
+let mathmlns = "http://www.w3.org/1998/Math/MathML";;
+let xmldiffns = "http://helm.cs.unibo.it/XmlDiff";;
+let helmns = "http://www.cs.unibo.it/helm";;
+
+type highlighted_nodes = Gdome.node list;;
+
+let rec make_visible (n: Gdome.node) =
+ match n#get_parentNode with
+    None -> ()
+  | Some p ->
+     match p#get_namespaceURI, p#get_localName with
+        Some nu, Some ln when
+         nu#to_string = mathmlns && ln#to_string = "maction" ->
+          (new Gdome.element_of_node p)#setAttribute
+            ~name:(Gdome.domString "selection")
+             ~value:(Gdome.domString "2") ;
+          make_visible p
+      | _,_ -> make_visible p
+;;
+
+let highlight_node ?(color="yellow") (doc: Gdome.document) (n: Gdome.node) =
+ let highlight (n: Gdome.node) =
+  let highlighter =
+   doc#createElementNS
+    ~namespaceURI:(Some (Gdome.domString mathmlns))
+    ~qualifiedName:(Gdome.domString "m:mstyle")
+  in
+   highlighter#setAttribute ~name:(Gdome.domString "mathbackground")
+    ~value:(Gdome.domString color) ;
+   highlighter#setAttributeNS
+    ~namespaceURI:(Some (Gdome.domString xmldiffns))
+    ~qualifiedName:(Gdome.domString "xmldiff:type")
+    ~value:(Gdome.domString "fake") ;
+   let parent = 
+    match n#get_parentNode with
+       None -> assert false
+     | Some p -> p
+   in
+    ignore
+     (parent#replaceChild ~oldChild:n ~newChild:(highlighter :> Gdome.node)) ;
+    ignore (highlighter#appendChild n) ;
+    (highlighter :> Gdome.node)
+ in
+  let rec find_mstylable_node n =
+   match n#get_namespaceURI, n#get_localName with
+      Some nu, Some ln when
+       nu#to_string = mathmlns &&
+        let ln = ln#to_string in
+         ln <> "mtr" && ln <> "mtd" -> n
+    | Some nu, Some ln when
+       nu#to_string = mathmlns &&
+        let ln = ln#to_string in
+         ln = "mtr" || ln = "mtd" ->
+prerr_endline "@@@ find_mstylable_node scendo";
+          let true_child =
+           match n#get_firstChild with
+              None -> assert false
+            | Some n -> n
+          in
+           find_mstylable_node true_child
+    | _,_ ->
+prerr_endline ("@@@ find_mstylable_node salgo da  " ^ match n#get_localName with Some n -> n#to_string | None -> "_") ;
+      match n#get_parentNode with
+         None -> assert false
+       | Some p -> find_mstylable_node p
+  in
+   let highlighter = highlight (find_mstylable_node n) in
+    make_visible highlighter ;
+    highlighter
+;;
+
+let highlight_nodes ~xrefs (doc:Gdome.document) =
+ let highlighted = ref [] in
+ let rec aux (n:Gdome.element) =
+  if
+   List.mem
+    (n#getAttributeNS ~namespaceURI:(Gdome.domString helmns)
+     ~localName:(Gdome.domString "xref"))#to_string
+    xrefs
+  then
+   highlighted :=
+    (highlight_node ~color:"#00ff00"(* light green *) doc (n :> Gdome.node))::
+    !highlighted ;
+  let children = n#get_childNodes in
+   for i = 0 to children#get_length - 1 do
+    match children#item i with
+       None -> assert false
+     | Some n ->
+        if n#get_nodeType = GdomeNodeTypeT.ELEMENT_NODE then
+         aux (new Gdome.element_of_node n)
+   done
+ in
+  aux doc#get_documentElement ;
+  !highlighted
+;;
+
+let dim_nodes =
+ List.iter 
+  (function (n : Gdome.node) ->
+    assert
+     (n#get_nodeType = GdomeNodeTypeT.ELEMENT_NODE &&
+      ((new Gdome.element_of_node n)#getAttributeNS
+        ~namespaceURI:(Gdome.domString xmldiffns)
+        ~localName:(Gdome.domString "type"))#to_string = "fake") ;
+    let true_child =
+     match n#get_firstChild with
+        None -> assert false
+      | Some n -> n in
+    let p =
+     match n#get_parentNode with
+        None -> assert false
+      | Some n -> n
+    in
+     ignore (p#replaceChild ~oldChild:n ~newChild:true_child)
+  )
+;;
+
 let update_dom ~(from : Gdome.document) (d : Gdome.document) =
  let rec aux (p: Gdome.node) (f: Gdome.node) (t: Gdome.node) =
 (* Perche' non andava?
@@ -56,7 +173,7 @@ prerr_endline ("XML_DIFF: preservo il nodo "^ nu#to_string ^ ":" ^ln#to_string);
               let processed = ref [] in
               for i = 0 to flen -1 do
                match fattrs#item i with
-                  None -> assert false
+                  None -> () (* CSC: sigh, togliere un nodo rompe fa decrescere la lunghezza ==> passare a un while *)
                 | Some attr ->
                     match attr#get_namespaceURI with
                        None ->
@@ -65,8 +182,12 @@ prerr_endline ("XML_DIFF: preservo il nodo "^ nu#to_string ^ ":" ^ln#to_string);
                          let name = attr#get_nodeName in
                           match tattrs#getNamedItem ~name with
                              None ->
-myprerr_endline ("XML_DIFF: rimuovo l'attributo " ^ name#to_string);
-                              ignore (f#removeChild attr)
+prerr_endline ("XML_DIFF: DOM 1; rimuovo l'attributo " ^ name#to_string);
+(*  CSC: questo non mi toglieva solo l'attributo, ma anche altri nodi qui
+    e la' ;-(
+                             ignore (f#removeChild attr)
+*)
+                             ignore (fattrs#removeNamedItem ~name)
                            | Some attr' ->
                               processed :=
                                (None,Some name)::!processed ;
@@ -81,7 +202,7 @@ myprerr_endline ("XML_DIFF: rimuovo l'attributo " ^ name#to_string);
 prerr_endline ("XML_DIFF: DOM 1; preservo l'attributo " ^ name#to_string);
                                    ()
                                | Some v1, Some v2 ->
-myprerr_endline ("XML_DIFF: DOM 1; rimpiazzo l'attributo " ^ name#to_string ^ ": old value=" ^ v1#to_string ^ ", new value=" ^ v2#to_string);
+prerr_endline ("XML_DIFF: DOM 1; rimpiazzo l'attributo " ^ name#to_string ^ ": old value=" ^ v1#to_string ^ ", new value=" ^ v2#to_string);
                                   let attr'' = from#importNode attr' true in
                                    ignore (fattrs#setNamedItem attr'')
                                | _,_ -> assert false
@@ -96,8 +217,14 @@ myprerr_endline ("XML_DIFF: DOM 1; rimpiazzo l'attributo " ^ name#to_string ^ ":
                           tattrs#getNamedItemNS ~namespaceURI ~localName
                          with
                             None ->
-myprerr_endline ("XML_DIFF: rimuovo l'attributo " ^ localName#to_string);
+prerr_endline ("XML_DIFF: DOM 2; rimuovo l'attributo " ^ namespaceURI#to_string ^ ":" ^ localName#to_string);
+(*  CSC: questo non mi toglieva solo l'attributo, ma anche altri nodi qui
+    e la' ;-(
                              ignore (f#removeChild attr)
+*)
+                             ignore
+                              (fattrs#removeNamedItemNS
+                                ~namespaceURI ~localName)
                           | Some attr' ->
                              processed :=
                               (Some namespaceURI,Some localName)::!processed ;
@@ -112,7 +239,7 @@ myprerr_endline ("XML_DIFF: rimuovo l'attributo " ^ localName#to_string);
 prerr_endline ("XML_DIFF: DOM 2; preservo l'attributo " ^ namespaceURI#to_string ^ ":" ^ localName#to_string);
                                    ()
                                | Some _, Some _ ->
-myprerr_endline ("XML_DIFF: DOM 2; rimpiazzo l'attributo " ^ namespaceURI#to_string ^ ":" ^ localName#to_string);
+prerr_endline ("XML_DIFF: DOM 2; rimpiazzo l'attributo " ^ namespaceURI#to_string ^ ":" ^ localName#to_string);
                                   let attr'' = from#importNode attr' true in
                                    ignore (fattrs#setNamedItem attr'')
                                | _,_ -> assert false
@@ -125,10 +252,10 @@ let debugs = ref "" in
                    let namespaceURI,localName =
                     match attr#get_namespaceURI with
                        None ->
-debugs := ("XML_DIFF: DOM 1.0; creo un nuovo attributo " ^ attr#get_nodeName#to_string) ;
+debugs := ("XML_DIFF: DOM 1; creo un nuovo attributo " ^ attr#get_nodeName#to_string) ;
                         None,attr#get_nodeName
                      | Some namespaceURI as v ->
-debugs := ("XML_DIFF: DOM 2.0; creo un nuovo attributo " ^ namespaceURI#to_string ^ ":" ^ match attr#get_localName with Some v -> v#to_string | None -> assert false);
+debugs := ("XML_DIFF: DOM 2; creo un nuovo attributo " ^ namespaceURI#to_string ^ ":" ^ match attr#get_localName with Some v -> v#to_string | None -> assert false);
                        v, match attr#get_localName with
                           None -> assert false
                         | Some v -> v
@@ -153,7 +280,7 @@ debugs := ("XML_DIFF: DOM 2.0; creo un nuovo attributo " ^ namespaceURI#to_strin
                         ) !processed)
                     then
                      let attr' = from#importNode attr false in
-myprerr_endline !debugs ;
+prerr_endline !debugs ;
                       ignore (fattrs#setNamedItem attr')
               done
           | _,_ -> assert false
@@ -168,14 +295,15 @@ prerr_endline "XML_DIFF: processo una coppia di figli" ;
               aux f he1 he2 ;
               dumb_diff (tl1,tl2)
            | [],tl2 ->
-myprerr_endline "XML_DIFF: appendo i nodi residui" ;
+prerr_endline ("XML_DIFF: appendo i nodi residui " ^ String.concat ", " (List.map (function n ->  match n#get_localName with Some s -> s#to_string | None -> "#" ^ (match n#get_nodeValue with Some s -> s#to_string | None -> "_") ^ "#") tl2)) ;
               List.iter
                (function n ->
                  let n' = from#importNode n true in
-                  ignore (f#appendChild n')
+                   ignore (f#appendChild n') ;
+                   ignore (highlight_node from n')
                ) tl2
            | tl1,[] ->
-myprerr_endline "XML_DIFF: cancello i nodi residui" ;
+prerr_endline ("XML_DIFF: cancello i nodi residui " ^ String.concat ", " (List.map (function n ->  match n#get_localName with Some s -> s#to_string | None -> "_") tl1)) ;
               List.iter (function n -> ignore (f#removeChild n)) tl1
          in
           let node_list_of_nodeList nl =
@@ -200,17 +328,36 @@ match n#get_nodeType with GdomeNodeTypeT.ATTRIBUTE_NODE -> prerr_endline "EUREKA
 done ;
 prerr_endline("XML_DIFF: from ha " ^ string_of_int fchildren#get_length ^ " nodi, ovvero " ^ string_of_int (List.length (node_list_of_nodeList fchildren)) ^ " figli");
 prerr_endline("XML_DIFF: to   ha " ^ string_of_int tchildren#get_length ^ " nodi, ovvero " ^ string_of_int (List.length (node_list_of_nodeList tchildren)) ^ " figli");
+prerr_endline ("XML_DIFF: chiamo dumb_diff su " ^ String.concat ", " (List.map (function n ->  match n#get_localName with Some s -> s#to_string | None -> "_") (node_list_of_nodeList fchildren)) ^ " e " ^ String.concat ", " (List.map (function n ->  match n#get_localName with Some s -> s#to_string | None -> "_") (node_list_of_nodeList tchildren))) ;
            dumb_diff
             (node_list_of_nodeList fchildren, node_list_of_nodeList tchildren)
    | t1,t2,_,_,_,_ when
       (t1 = GdomeNodeTypeT.ELEMENT_NODE || t1 = GdomeNodeTypeT.TEXT_NODE) &&
       (t2 = GdomeNodeTypeT.ELEMENT_NODE || t2 = GdomeNodeTypeT.TEXT_NODE) ->
-       let t' = from#importNode t true in
-myprerr_endline "XML_DIFF: importo il nodo" ;
+       if
+        t1 = GdomeNodeTypeT.ELEMENT_NODE &&
+        ((new Gdome.element_of_node f)#getAttributeNS
+          ~namespaceURI:(Gdome.domString xmldiffns)
+          ~localName:(Gdome.domString "type"))#to_string = "fake"
+       then
+        let true_child =
+         match f#get_firstChild with
+            None -> assert false
+          | Some n -> n
+        in
+         begin
+prerr_endline ("%%% CANCELLO HIGHLIGHTER " ^ (match f#get_localName with Some s -> s#to_string | None -> "_") ^ " CON DENTRO " ^ (match true_child#get_localName with Some s -> s#to_string | None -> "_")) ;
+          ignore (p#replaceChild ~oldChild:f ~newChild:true_child) ;
+          aux p true_child t
+         end
+       else
+        let t' = from#importNode t true in
+prerr_endline ("%%% XML_DIFF: importo il nodo " ^ match t'#get_localName with Some n -> n#to_string | None -> "_") ;
 (*
 prerr_endline ("Rimpiazzo" ^ (match f#get_namespaceURI with Some s -> s#to_string) ^ ":" ^ (match f#get_localName with Some s -> s#to_string) ^ " con " ^ (match t#get_namespaceURI with Some s -> s#to_string) ^ ":" ^ (match t#get_localName with Some s -> s#to_string) ^ " in " ^ (match p#get_localName with Some s -> s#to_string | None -> "_")) ;
 *)
-        ignore (p#replaceChild ~newChild:t' ~oldChild:f)
+         ignore (p#replaceChild ~newChild:t' ~oldChild:f) ;
+         ignore (highlight_node from t')
    | _,_,_,_,_,_ -> assert false
  in
   try
@@ -219,32 +366,28 @@ prerr_endline ("Rimpiazzo" ^ (match f#get_namespaceURI with Some s -> s#to_strin
     (d#get_documentElement :> Gdome.node)
   with
      (GdomeInit.DOMException (e,msg) as ex) ->
-(*
+(* CSC: Non si puo' per problemi di linking ;-(
     let module E = GdomeDOMExceptionT in
 *)
        prerr_endline
         ("DOM EXCEPTION: " ^ msg ^ " --- " ^
-string_of_int (Obj.magic e)) ;
-       raise ex
- (*
-        match e with
-           E.NO_ERR -> "NO_ERR"
-         | E.INDEX_SIZE_ERR -> "INDEX_SIZE_ERR"
-         | E.DOMSTRING_SIZE_ERR -> "DOMSTRING_SIZE_ERR"
-         | E.HIERARCHY_REQUEST_ERR -> "HIERARCHY_REQUEST_ERR"
-         | E.WRONG_DOCUMENT_ERR -> "WRONG_DOCUMENT_ERR"
-         | E.INVALID_CHARACTER_ERR -> "INVALID_CHARACTER_ERR"
-         | E.NO_DATA_ALLOWED_ERR -> "NO_DATA_ALLOWER_ERR"
-         | E.NO_MODIFICATION_ALLOWED_ERR -> "NO_MODIFICATION_ALLOWED_ERR"
-         | E.NOT_FOUND_ERR -> "NOT_FOUND_ERR"
-         | E.NOT_SUPPORTED_ERR -> "NOT_SUPPORTED_ERR"
-         | E.INUSE_ATTRIBUTE_ERR -> "INUSE_ATTRIBUTE_ERR"
-         | E.INVALID_STATE_ERR -> "INVALID_STATE_ERR"
-         | E.SYNTAX_ERR -> "SYNTAX_ERR"
-         | E.INVALID_MODIFICATION_ERR -> "INVALID_MODIFICATION_ERR"
-         | E.NAMESPACE_ERR -> "NAMESPACE_ERR"
-         | E.INVALID_ACCESS_ERR -> "INVALID_ACCESS_ERR"
-*)
+          match e with
+             GdomeDOMExceptionT.NO_ERR -> "NO_ERR"
+           | GdomeDOMExceptionT.INDEX_SIZE_ERR -> "INDEX_SIZE_ERR"
+           | GdomeDOMExceptionT.DOMSTRING_SIZE_ERR -> "DOMSTRING_SIZE_ERR"
+           | GdomeDOMExceptionT.HIERARCHY_REQUEST_ERR -> "HIERARCHY_REQUEST_ERR"
+           | GdomeDOMExceptionT.WRONG_DOCUMENT_ERR -> "WRONG_DOCUMENT_ERR"
+           | GdomeDOMExceptionT.INVALID_CHARACTER_ERR -> "INVALID_CHARACTER_ERR"
+           | GdomeDOMExceptionT.NO_DATA_ALLOWED_ERR -> "NO_DATA_ALLOWER_ERR"
+           | GdomeDOMExceptionT.NO_MODIFICATION_ALLOWED_ERR -> "NO_MODIFICATION_ALLOWED_ERR"
+           | GdomeDOMExceptionT.NOT_FOUND_ERR -> "NOT_FOUND_ERR"
+           | GdomeDOMExceptionT.NOT_SUPPORTED_ERR -> "NOT_SUPPORTED_ERR"
+           | GdomeDOMExceptionT.INUSE_ATTRIBUTE_ERR -> "INUSE_ATTRIBUTE_ERR"
+           | GdomeDOMExceptionT.INVALID_STATE_ERR -> "INVALID_STATE_ERR"
+           | GdomeDOMExceptionT.SYNTAX_ERR -> "SYNTAX_ERR"
+           | GdomeDOMExceptionT.INVALID_MODIFICATION_ERR -> "INVALID_MODIFICATION_ERR"
+           | GdomeDOMExceptionT.NAMESPACE_ERR -> "NAMESPACE_ERR"
+           | GdomeDOMExceptionT.INVALID_ACCESS_ERR -> "INVALID_ACCESS_ERR")
   | e ->
     prerr_endline "PROBLEMA" ;
     raise e