]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-outputter.cc
release: 1.3.28
[lilypond.git] / lily / paper-outputter.cc
1 /*
2   paper-outputter.cc -- implement Paper_outputter
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   Jan Nieuwenhuizen <janneke@gnu.org>
8 */
9
10 #include <time.h>
11 #include <fstream.h>
12 #include <math.h>
13 #include <iostream.h>
14
15 #include "dimensions.hh"
16 #include "dictionary-iter.hh"
17 #include "virtual-methods.hh"
18 #include "paper-outputter.hh"
19 #include "paper-stream.hh"
20 #include "molecule.hh"
21 #include "array.hh"
22 #include "string-convert.hh"
23 #include "debug.hh"
24 #include "lookup.hh"
25 #include "main.hh"
26 #include "scope.hh"
27 #include "identifier.hh"
28 #include "lily-version.hh"
29 #include "atom.hh"
30
31 Paper_outputter::Paper_outputter ()
32 {
33   molecules_ = gh_cons (SCM_EOL, SCM_EOL);
34   last_cons_ = molecules_;
35 }
36
37
38 void
39 Paper_outputter::output_header ()
40 {
41   if (safe_global_b)
42     {
43
44       gh_define ("security-paranoia", SCM_BOOL_T);      
45     }
46   String s = String ("(eval (") + output_global_ch + "-scm 'all-definitions))";
47   ly_eval_str (s.ch_C ());
48   
49   String creator;
50   if (no_timestamps_global_b)
51     creator = gnu_lilypond_str ();
52   else
53     creator = gnu_lilypond_version_str ();
54   
55   String generate;
56   if (no_timestamps_global_b)
57     generate = ".";
58   else
59     {
60       generate = _ (", at ");
61       time_t t (time (0));
62       generate += ctime (&t);
63       generate = generate.left_str (generate.length_i () - 1);
64     }
65
66   SCM args_scm = 
67     gh_list (ly_str02scm (creator.ch_l ()),
68              ly_str02scm (generate.ch_l ()), SCM_UNDEFINED);
69
70
71   SCM scm = gh_cons (ly_symbol2scm ("header"), args_scm);
72   output_scheme (scm);
73 }
74
75 void
76 Paper_outputter::output_molecule (Molecule const*m, Offset o, char const *nm)
77 {
78   if (flower_dstream)
79     {
80       output_comment (nm);
81     }
82
83   SCM offset_sym = ly_symbol2scm ("translate-atom"); 
84   for (SCM ptr = gh_cdr (m->atom_list_); ptr != SCM_EOL; ptr = gh_cdr (ptr))
85     {
86       SCM func =  gh_car (ptr);
87       SCM funcptr = func;
88
89       Offset a_off (0,0);
90       while (gh_pair_p (funcptr))
91         {
92           if (gh_car (funcptr) == offset_sym)
93             {
94               SCM quot = gh_cadr (funcptr);
95               a_off += ly_scm2offset (gh_cadr (quot));
96             }
97           funcptr = scm_last_pair (funcptr);
98           if (funcptr != SCM_EOL )
99             {
100               funcptr = gh_car (funcptr);
101             }
102         }
103       
104       a_off += o;
105       
106       Axis a = X_AXIS;
107       while (a < NO_AXES)
108         {
109           if (abs(a_off[a]) > 30 CM
110               || isinf (a_off[a]) || isnan (a_off[a]))
111             {
112               programming_error ("Improbable offset for object: setting to zero");
113               a_off[a] =  0.0;
114             }
115           incr (a);
116         }
117
118         
119       SCM box_scm
120         = gh_list (ly_symbol2scm ("placebox"),
121                    gh_double2scm (a_off[X_AXIS]),
122                    gh_double2scm (a_off[Y_AXIS]),
123                    func,
124                    SCM_UNDEFINED);
125
126       output_scheme (box_scm);
127     }
128 }
129
130 void
131 Paper_outputter::output_comment (String str)
132 {
133   output_scheme (gh_list (ly_symbol2scm ("comment"),
134                           ly_str02scm ((char*)str.ch_C()),
135                           SCM_UNDEFINED)
136                  );
137 }
138
139
140 void
141 Paper_outputter::output_scheme (SCM scm)
142 {
143   SCM c = gh_cons (scm,gh_cdr (last_cons_));
144   gh_set_cdr_x(last_cons_, c);
145   last_cons_ = c;
146 }
147
148
149 void
150 Paper_outputter::dump_onto (Paper_stream *ps)
151 {
152   if (String (output_global_ch) == "scm")
153 #if 1  // both are fine
154     {
155       /*
156         default to stdin
157        */
158       int fd = 1;
159       if (ofstream* of = dynamic_cast<ofstream*> (ps->os))
160         fd = of->rdbuf ()->fd ();
161       SCM port = scm_fdes_to_port (fd, "a", SCM_EOL);
162
163       /*
164          lilypond -f scm x.ly
165          guile -s x.scm
166        */
167       scm_display (gh_str02scm (
168         ";;; Usage: guile -s x.scm > x.tex\n"
169         "(primitive-load-path 'lily.scm)\n"
170         "(scm-as-output)\n"
171         ";(scm-tex-output)\n"
172         ";(scm-ps-output)\n"
173         "(map (lambda (x) (display (eval x))) '(\n"
174         ), port);
175
176       SCM newline = gh_str02scm ("\n");
177       for (SCM s = gh_cdr (molecules_); gh_pair_p (s); s = gh_cdr (s))
178         {
179           scm_write (gh_car (s), port);
180           scm_display (newline, port);
181           scm_flush (port);
182         }
183       scm_display (gh_str02scm ("))"), port);
184       scm_display (newline, port);
185       scm_flush (port);
186       scm_close_port (port);
187     }
188 #else
189     {
190       /*
191          lilypond -f scm x.ly
192          guile -s x.scm
193        */
194       if (output_global_ch == String ("scm"))
195         *ps << ""
196           ";;; Usage: guile -s x.scm > x.tex\n"
197           "(primitive-load-path 'lily.scm)\n"
198           "(scm-tex-output)\n"
199           ";(scm-ps-output)\n"
200           "(map (lambda (x) (display (eval x))) '(\n"
201         ;
202       for (SCM s = gh_cdr (molecules_); gh_pair_p (s); s = gh_cdr (s))
203         {
204           SCM result =  scm_eval (scm_listify (ly_symbol2scm ("scm->string"),
205                                                ly_quote_scm (gh_car (s)), SCM_UNDEFINED));
206           
207           *ps << ly_scm2string (result);
208         }
209       *ps << "))";
210     }
211 #endif
212   
213   else
214     {
215       for (SCM s = gh_cdr (molecules_); gh_pair_p (s); s = gh_cdr (s))
216         {
217           SCM result = scm_eval (gh_car (s));
218           char *c=gh_scm2newstr (result, NULL);
219           
220           *ps << c;
221           free (c);
222         }
223   }
224 }
225
226 void
227 Paper_outputter::output_scope (Scope *scope, String prefix)
228 {
229   for (Scope_iter i (*scope); i.ok (); i++)
230     {
231       if (dynamic_cast<String_identifier*> (i.val ()))
232         {
233           String val = *i.val()->access_content_String (false);
234
235           output_String_def (prefix + i.key (), val);
236         }
237       else if(dynamic_cast<Real_identifier*> (i.val ()))
238         {
239           Real val  = *i.val ()->access_content_Real (false);
240
241           output_Real_def (prefix + i.key (), val);       
242         }
243       else if (dynamic_cast<int_identifier*> (i.val ()))
244         {
245           int val  = *i.val ()->access_content_int (false);       
246           
247           output_int_def (prefix + i.key (), val);        
248         }
249     }
250 }
251
252 void
253 Paper_outputter::output_version ()
254 {
255   String id_str = "Lily was here";
256   if (no_timestamps_global_b)
257     id_str += ".";
258   else
259     id_str += String (", ") + version_str ();
260
261   output_String_def ( "mudelatagline", id_str);
262   output_String_def ( "LilyPondVersion", version_str ());
263 }
264
265 void
266 Paper_outputter::start_line (Real height)
267 {
268   if (height > 50 CM)
269     {
270       programming_error ("Improbable system height");
271       height = 50 CM;
272     }
273   SCM scm = gh_list (ly_symbol2scm ("start-line"),
274                      gh_double2scm (height),
275                      SCM_UNDEFINED);
276   output_scheme (scm);
277 }
278
279 void
280 Paper_outputter::output_font_def (int i, String str)
281 {
282   SCM scm = gh_list (ly_symbol2scm ("font-def"),
283                      gh_int2scm (i),
284                      ly_str02scm (str.ch_l ()),
285                      SCM_UNDEFINED);
286
287   output_scheme (scm);
288 }
289
290 void
291 Paper_outputter::output_Real_def (String k, Real v)
292 {
293   
294   SCM scm = gh_list (ly_symbol2scm ("lily-def"),
295                      ly_str02scm (k.ch_l ()),
296                      ly_str02scm (to_str(v).ch_l ()),
297                      SCM_UNDEFINED);
298   output_scheme (scm);
299
300   //  gh_define (k.ch_l (), gh_double2scm (v));
301 }
302
303 void
304 Paper_outputter::output_String_def (String k, String v)
305 {
306   
307   SCM scm = gh_list (ly_symbol2scm ("lily-def"),
308                      ly_str02scm (k.ch_l ()),
309                      ly_str02scm (v.ch_l ()),
310                      SCM_UNDEFINED);
311   output_scheme (scm);
312
313   // gh_define (k.ch_l (), ly_str02scm (v.ch_l ()));
314 }
315
316 void
317 Paper_outputter::output_int_def (String k, int v)
318 {
319   SCM scm = gh_list (ly_symbol2scm ("lily-def"),
320                      ly_str02scm (k.ch_l ()),
321                      ly_str02scm (to_str (v).ch_l ()),
322                      SCM_UNDEFINED);
323   output_scheme (scm);
324
325   // gh_define (k.ch_l (), gh_int2scm (v));
326 }
327
328
329
330 void
331 Paper_outputter::stop_line ()
332 {
333   SCM scm = gh_list (ly_symbol2scm ("stop-line"), SCM_UNDEFINED);
334   output_scheme (scm);
335 }
336
337 void
338 Paper_outputter::stop_last_line ()
339 {
340   SCM scm = gh_list (ly_symbol2scm ("stop-last-line"), SCM_UNDEFINED);
341   output_scheme (scm);
342   scm = gh_list (ly_symbol2scm ("end-output"), SCM_UNDEFINED);
343   output_scheme (scm);
344 }
345
346