]> matita.cs.unibo.it Git - helm.git/blob - helm/software/lambda-delta/src/xml/xmlLibrary.ml
af6245c9f4371d3211f2429f43f516c184969d7e
[helm.git] / helm / software / lambda-delta / src / xml / xmlLibrary.ml
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department, University of Bologna, Italy.                     
5     ||I||                                                                
6     ||T||  HELM is free software; you can redistribute it and/or         
7     ||A||  modify it under the terms of the GNU General Public License   
8     \   /  version 2 or (at your option) any later version.              
9      \ /   This software is distributed as is, NO WARRANTY.              
10       V_______________________________________________________________ *)
11
12 module F = Filename
13 module U = NUri
14 module C = Cps
15 module H = Hierarchy
16 module E = Entity
17 module N = Level
18
19 (* internal functions *******************************************************)
20
21 let base = "xml"
22
23 let obj_ext = ".xml"
24
25 let root = "ENTITY"
26
27 let system = "http://helm.cs.unibo.it/lambda-delta/" ^ base ^ "/ld.dtd"
28
29 let path_of_uri xdir uri =
30    let base = F.concat xdir base in 
31    F.concat base (Str.string_after (U.string_of_uri uri) 3)
32
33 (* interface functions ******************************************************)
34
35 type och = string -> unit
36
37 type attr = string * string
38
39 type pp = och -> int -> unit
40
41 let attribute out (name, contents) =
42    if contents <> "" then begin
43       out " "; out name; out "=\""; out contents; out "\""
44    end
45
46 let xml out version encoding =
47    out "<?xml";
48       attribute out ("version", version);
49       attribute out ("encoding", encoding);
50    out "?>\n\n"
51
52 let doctype out root system =
53    out "<!DOCTYPE "; out root; out " SYSTEM \""; out system; out "\">\n\n"
54
55 let tag tag attrs ?contents out indent =
56    let spc = String.make indent ' ' in
57    out spc; out "<"; out tag; List.iter (attribute out) attrs;
58    match contents with
59       | None      -> out "/>\n"
60       | Some cont -> 
61          out ">\n"; cont out (indent + 3); out spc; 
62          out "</"; out tag; out ">\n"
63
64 let sort = "Sort"
65
66 let lref = "LRef"
67
68 let gref = "GRef"
69
70 let cast = "Cast"
71
72 let appl = "Appl"
73
74 let proj = "Proj"
75
76 let abst = "Abst"
77
78 let abbr = "Abbr"
79
80 let void = "Void"
81
82 let position i =
83    "position", string_of_int i
84
85 let offset j = 
86    let contents = if j > 0 then string_of_int j else "" in
87    "offset", contents
88
89 let uri u =
90    "uri", U.string_of_uri u
91
92 let arity n =
93    let contents = if n > 1 then string_of_int n else "" in
94    "arity", contents
95
96 let name a =
97    let map f i n r s =
98       let n = if r then n else "-" ^ n in 
99       let spc = if i then "" else " " in
100       f (s ^ n ^ spc)
101    in
102    let f s = "name", s in
103    E.names f map a ""
104
105 let mark a =
106    let err () = "mark", "" in
107    let f i = "mark", string_of_int i in
108    E.mark err f a
109
110 let level n =
111    "level", N.to_string n
112
113 (* TODO: the string s must be quoted *)
114 let meta a =
115    let err () = "meta", "" in
116    let f s = "meta", s in
117    E.meta err f a
118
119 let export_entity pp_term si xdir (a, u, b) =
120    let path = path_of_uri xdir u in
121    let _ = Sys.command (Printf.sprintf "mkdir -p %s" (F.dirname path)) in
122    let och = open_out (path ^ obj_ext) in
123    let out = output_string och in
124    xml out "1.0" "UTF-8"; doctype out root system;
125    let a = E.Name (U.name_of_uri u, true) :: a in
126    let attrs = [uri u; name a; mark a; meta a] in 
127    let contents = match b with
128       | E.Abst (n, w) -> tag "ABST" (level n :: attrs) ~contents:(pp_term w) 
129       | E.Abbr v      -> tag "ABBR" attrs ~contents:(pp_term v)
130       | E.Void        -> assert false
131    in
132    let opts = if si then "si" else "" in
133    let shp = H.string_of_graph () in
134    let attrs = ["hierarchy", shp; "options", opts] in
135    tag root attrs ~contents out 0;
136    close_out och