summaryrefslogtreecommitdiff
path: root/support/syngen/src/latexcode.ml
blob: 3cc9f3c2417ad90830c3147576a942ff6a00286f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
open Boxes
open Picture

let rec tex_string = function
    [] -> ""
  | h::t -> let chr = match h
                       with '#' -> "\char'43{}"
                          | '$' -> "\char'44{}"
                          | '%' -> "\char'45{}"
                          | '&' -> "\char'46{}"
                          | '*' -> "\char'52{}"
                          | '^' -> "\char'136{}"
                          | '_' -> "\char'137{}"
                          | '{' -> "\char'173{}"
                          | '}' -> "\char'175{}"
                          | '~' -> "\char'176{}"
                          | '\\' -> "\char'134{}"
                          | _ -> String.make 1 h
            in (tex_string t) ^ chr

let last s = List.hd (List.rev s)

let strbalance = "\\rule[-\\bdepth]{0pt}{\\bheight}"
and strfont = "\\ttfamily{}"
and epsilon = 1.0e-10

let generate box_con box_off char_off box_height box_sep_frac t = 
  let rec out_list xend yoff = function
      [] -> []
    | h :: s -> 
        let difference = xend -. dim_l h -. box_con 
        and box_sep = box_height *. box_sep_frac 
        and ypos = if yoff -. dim_h h < epsilon then 0. 
                   else yoff -. dim_h h in
        if abs_float difference < epsilon then
          SubPicture ((box_con, ypos), generate_aux false h, []) ::
          out_list xend (ypos -. box_sep) s
        else
          SubPicture ((box_con, ypos), generate_aux false h, []) ::
          Line ((box_con +. dim_l h, ypos +. dim_rc h), 1, 0, 
               difference, []) ::
          out_list xend (ypos -. box_sep) s
  and generate_aux islast = function
      TermBox (d, s) -> 
        Picture (d.l, d.h, 0., 0., [ 
          Line ((0., d.h -. d.lc), 1, 0, box_con, [Arrowhead]);
          Oval ((d.l /. 2., d.h /. 2.), d.l -. 2. *. box_con, box_height, []); 
          Text ((d.l /. 2., d.h /. 2.), strfont ^ tex_string s ^ strbalance, 
               []);
          Line ((d.l -. box_con, d.rc), 1, 0, box_con, 
               if islast then [Arrowhead] else [])
        ])
    | ParamBox (d, s) -> 
        Picture (d.l, d.h, 0., 0., [ 
          Line ((0., d.h -. d.lc), 1, 0, box_con, [Arrowhead]);
          Framebox ((box_con, 0.), d.l -. 2. *. box_con, box_height, 
                   [Dashed 2.]); 
          Text ((d.l /. 2., d.h /. 2.), strfont ^ tex_string s ^ strbalance, 
               []);
          Line ((d.l -. box_con, d.rc), 1, 0, box_con, 
               if islast then [Arrowhead] else [])
        ])
    | NonTermBox (d, s) ->
        Picture (d.l, d.h, 0., 0., [ 
          Line ((0., d.h -. d.lc), 1, 0, box_con, [Arrowhead]);
          Framebox ((box_con, 0.), d.l -. 2. *. box_con, box_height, []); 
          Text ((d.l /. 2., d.h /. 2.), strfont ^ tex_string s ^ strbalance, 
               []);
          Line ((d.l -. box_con, d.rc), 1, 0, box_con, 
               if islast then [Arrowhead] else [])
        ])
    | OptBox (d, t) -> 
        Picture (d.l, d.h, 0., 0., [ 
          Line ((0., d.h -. d.lc), 1, 0, box_con, []);
          SubPicture ((box_con, box_height /. 2.), generate_aux false t, []);
          Line ((box_con, d.h -. d.lc), 0, -1, d.h -. d.lc, []);
          Line ((box_con, 0.), 1, 0, d.l -. 2. *. box_con, []);
          Line ((d.l -. box_con, 0.), 0, 1, d.rc, [Arrowhead]);
          Line ((d.l -. box_con, d.rc), 1, 0, box_con, 
               if islast then [Arrowhead] else [])
        ])
    | RepBox (d, t) -> 
        Picture (d.l, d.h, 0., 0., [ 
          Line ((0., d.h -. d.lc), 1, 0, box_con, []);
          SubPicture ((box_con, 0.), generate_aux false t, []);
          Line ((box_con, d.h), 0, -1, d.lc, [Arrowhead]);
          Line ((d.l -. box_con, d.h), -1, 0, d.l -. 2. *. box_con, []);
          Line ((d.l -. box_con, d.h), 0, -1, d.h -. d.rc, []);
          Line ((d.l -. box_con, d.rc), 1, 0, box_con, 
               if islast then [Arrowhead] else [])
        ])
    | TermRepBox (d, t1, TermBox (d1, s)) -> 
        Picture (d.l, d.h, 0., 0., [ 
          Line ((0., d.h -. d.lc), 1, 0, box_con, []);
          SubPicture ((box_con, 0.), generate_aux false t1, []);
          Oval ((d.l /. 2., d.h -. box_height /. 2.), d1.l, box_height, []);
          Text ((d.l /. 2., d.h -. box_height /. 2.), 
               strfont ^ tex_string s ^ strbalance, []);
          Line ((box_con, d.h -. box_height /. 2.), 0, -1, 
               d.lc -. box_height /. 2., [Arrowhead]);
          Line ((d.l -. box_con, d.h -. box_height /. 2.), -1, 0, 
               d.l /. 2. -. box_con -. d1.l /. 2., []);
          Line ((box_con, d.h -. box_height /. 2.), 1, 0,  
               d.l /. 2. -. box_con -. d1.l /. 2., []);
          Line ((d.l -. box_con, d.h -. box_height /. 2.), 0, -1,  
               d.h -. d.rc -. box_height /. 2., []);
          Line ((d.l -. box_con, d.rc), 1, 0, box_con, 
               if islast then [Arrowhead] else [])
        ])
    | OptRepBox (d, t) -> 
        Picture (d.l, d.h, 0., 0., [ 
          Line ((0., d.h -. d.lc), 1, 0, box_con, []);
          SubPicture ((box_con, box_height /. 2.), generate_aux false t, []);
          Line ((box_con, d.h), 0, -1, d.lc, [Arrowhead]);
          Line ((d.l -. box_con, d.h), -1, 0, d.l -. 2. *. box_con, []);
          Line ((d.l -. box_con, d.h), 0, -1, d.h -. d.rc, []);
          Line ((box_con, d.h -. d.lc), 0, -1, d.h -. d.lc, []);
          Line ((box_con, 0.), 1, 0, d.l -. 2. *. box_con, []);
          Line ((d.l -. box_con, 0.), 0, 1, d.rc, [Arrowhead]);
          Line ((d.l -. box_con, d.rc), 1, 0, box_con,
               if islast then [Arrowhead] else [])
        ])
    | OrBoxList (d, l) ->
        Picture (d.l, d.h, 0., 0.,  
          Line ((0., d.h -. d.lc), 1, 0, box_con, []) ::
          (out_list (d.l -. box_con) d.h l) @ [
            Line ((d.l -. box_con, d.h -. dim_h (List.hd l) +. 
                                   dim_rc (List.hd l)), 0, -1, 
                 d.h -. dim_h (List.hd l) +. dim_rc (List.hd l) -. d.rc, 
                 [Arrowhead]);
            Line ((box_con, d.h -. d.lc), 0, -1, 
                 d.h -. d.lc -. (let lst = last l 
                                 in dim_h lst -. dim_lc lst), []);
            Line ((d.l -. box_con, d.rc), 1, 0, box_con, 
               if islast then [Arrowhead] else [])
          ])
    | ConBox (d, t1, t2) ->
        let a = dim_h t2 -. dim_lc t2 -. dim_rc t1 in
        Picture (d.l, d.h, 0., 0., [ 
          SubPicture ((0., if a > 0. then a else 0.), generate_aux false t1, 
                     []);
          SubPicture ((dim_l t1 -. box_con, if a < 0. then ~-.a else 0.), 
                     generate_aux islast t2, [])
        ])
    | _ -> raise (Failure "Bug im Parser!")
in generate_aux true t