]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-outputter.cc
release: 1.1.50
[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--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   Jan Nieuwenhuizen <janneke@gnu.org>
8 */
9
10 #include <time.h>
11 #include <fstream.h>
12
13 #include "dimensions.hh"
14 #include "dictionary-iter.hh"
15 #include "virtual-methods.hh"
16 #include "paper-outputter.hh"
17 #include "paper-stream.hh"
18 #include "molecule.hh"
19 #include "array.hh"
20 #include "string-convert.hh"
21 #include "debug.hh"
22 #include "lookup.hh"
23 #include "main.hh"
24 #include "scope.hh"
25 #include "identifier.hh"
26 #include "lily-version.hh"
27 #include "atom.hh"
28
29 // urg
30 static SCM port = 0;
31
32 Paper_outputter::Paper_outputter (Paper_stream *s)
33 {
34   port = 0;
35   outstream_l_ = s;
36   output_header ();
37 }
38
39 Paper_outputter::~Paper_outputter ()
40 {
41   SCM scm = gh_list (ly_symbol ("end-output"), SCM_UNDEFINED);
42   output_scheme (scm);
43
44   if (String (output_global_ch) == "scm")
45     {
46 #if 1
47       scm_display (gh_str02scm (")))\n"), port);
48       scm_fflush (port);
49 #else
50       *outstream_l_->os << ")";
51 #endif
52     }
53 }
54
55 void
56 Paper_outputter::output_header ()
57 {
58   if (safe_global_b)
59     {
60       ly_set_scm ("security-paranoia", SCM_BOOL_T);
61       //      gh_eval_str ("(set! security-paranoia #t)");
62     }
63   String s = String ("(eval (") + output_global_ch + "-scm 'all-definitions))";
64   gh_eval_str (s.ch_C ());
65   
66   String creator;
67   if (no_timestamps_global_b)
68     creator = gnu_lilypond_str ();
69   else
70     creator = gnu_lilypond_version_str ();
71   
72   String generate;
73   if (no_timestamps_global_b)
74     generate = ".\n";
75   else
76     {
77       generate = _ (", at ");
78       time_t t (time (0));
79       generate += ctime (&t);
80       //urg
81     }
82
83   SCM args_scm = 
84     gh_list (gh_str02scm (creator.ch_l ()),
85              gh_str02scm (generate.ch_l ()), SCM_UNDEFINED);
86
87 #ifndef NPRINT
88   DOUT << "output_header\n";
89   if (check_debug && !monitor->silent_b ("Guile"))
90     {
91       gh_display (args_scm); gh_newline ();
92     }
93 #endif
94
95   SCM scm = gh_cons (header_scm_sym, args_scm);
96   output_scheme (scm);
97 }
98
99 void
100 Paper_outputter::output_molecule (Molecule const*m, Offset o, char const *nm)
101 {
102   if (check_debug)
103     *outstream_l_ << String ("\n%start: ") << nm << "\n";
104
105
106   if (check_debug)
107     {
108       output_comment (nm);
109     }
110       
111 #ifdef ATOM_SMOB
112   for (SCM ptr = m->atom_list_; ptr != SCM_EOL; ptr = SCM_CDR(ptr))
113     {
114       Atom *i = Atom::atom_l (SCM_CAR(ptr));
115 #else
116   for (Cons<Atom> *ptr = m->atom_list_; ptr; ptr = ptr->next_)
117     {
118       Atom * i = ptr->car_;
119 #endif
120       Offset a_off = i->off_;
121       a_off += o;
122
123       if (!i->func_)
124         continue; 
125
126       if (a_off.length () > 100 CM)
127         {
128           warning (_f("Improbable offset for object type `%s\'", nm));
129           Axis a  =X_AXIS;
130           while (a < NO_AXES)
131             {
132               if (abs(a_off[a]) > 50 CM)
133                 a_off[a] = 50 CM;
134               incr (a);
135             }
136         }
137         
138       if (i->font_)
139         {
140           output_scheme (gh_list (ly_symbol ("select-font"),
141                                   gh_str02scm (symbol_to_string (i->font_).ch_C()),
142                                   SCM_UNDEFINED));
143         }
144
145       SCM box_scm
146         = gh_list (placebox_scm_sym,
147                    gh_double2scm (a_off.x ()),
148                    gh_double2scm (a_off.y ()),
149                    SCM(i->func_),
150                    SCM_UNDEFINED);
151       
152       output_scheme (box_scm);
153     }
154 }
155
156 void
157 Paper_outputter::output_comment (String str)
158 {
159   if (String (output_global_ch) == "scm")
160     {
161       *outstream_l_ << "; " << str << '\n';
162     }
163   else
164     {
165       *outstream_l_ << "% " << str << "\n";
166     }
167 }
168
169
170 void
171 Paper_outputter::output_scheme (SCM scm)
172 {
173   if (String (output_global_ch) == "scm")
174     {
175 #if 1
176       /*
177        we'd rather use C++ i/o iso Guile's, but how?
178        and: they can't be mixed (or synchronised) easily?
179        */
180
181       // urg
182       if (!port)
183         {
184           int fd = 1;
185           ofstream * of = dynamic_cast<ofstream*> (outstream_l_->os);
186           if (of)
187             fd = of->rdbuf()->fd();
188           FILE *file = fdopen (fd, "a");
189           port = scm_standard_stream_to_port (file, "a", "");
190           scm_display (gh_str02scm (
191             "(primitive-load-path 'lily.scm)\n"
192             "(eval (tex-scm 'all-definitions))\n"
193             ";(eval (ps-scm 'all-definitions))\n"
194             "(display (map (lambda (x) (string-append (eval x) \"%\\n\")) '(\n"
195             ), port);
196         }
197
198       scm_write (scm, port);
199       // duh
200       scm_display (gh_str02scm ("\n"), port);
201       scm_fflush (port);
202 #else
203       static bool first = true;
204       if (first)
205         {
206           *outstream_l_->os << ""
207             "(primitive-load-path 'lily.scm)\n"
208             "(eval (tex-scm 'all-definitions))\n"
209             ";(eval (ps-scm 'all-definitions))\n"
210             "(display (map (lambda (x) (string-append (eval x) \"\\n\")) '(\n"
211             ;
212         }
213
214       /*
215         why doesn't this work?
216
217         ERROR: In procedure gh_scm2newstr:
218         ERROR: Wrong type argument in position 3: 
219           (header "GNU LilyPond 1.1.49.jcn1" ", at Tue Jun 22 20:58:17 1999")
220
221         or:
222
223         ERROR: In procedure symbol->string:
224         ERROR: Wrong type argument in position 1: 
225           (header "GNU LilyPond 1.1.49.jcn2" ", at Wed Jun 23 18:42:14 1999")
226
227         eg, two ways to print '(foo bar)'
228
229         SCM scm = gh_list (ly_symbol ("foo"), gh_str2scm ("bar"), SCM_UNDEFINED);
230         scm_write (scm, port);
231         puts (gh_xxx2newstr (scm, 0));
232        */
233
234       char* p;
235       //p = gh_scm2newstr (scm, 0);
236       //p = gh_symbol2newstr (scm, 0);
237       //p = gh_scm2newstr (scm_symbol_to_string (scm), 0);
238       //p = gh_symbol2newstr (scm_symbol_to_string (scm), 0);
239       //*outstream_l_->os << p << endl;
240       *outstream_l_->os << symbol_to_string (scm) << endl;
241 #endif
242     }
243   else
244     {
245       SCM result = scm_eval (scm);
246       char *c=gh_scm2newstr (result, NULL);
247
248       *outstream_l_ << c;
249       free (c);
250     }
251 }
252
253 void
254 Paper_outputter::output_scope (Scope *scope, String prefix)
255 {
256   for (Scope_iter i (*scope); i.ok (); i++)
257     {
258       if (dynamic_cast<String_identifier*> (i.val ()))
259         {
260           String val = *i.val()->access_content_String (false);
261
262           output_String_def (prefix + i.key (), val);
263         }
264       else if(dynamic_cast<Real_identifier*> (i.val ()))
265         {
266           Real val  = *i.val ()->access_content_Real (false);
267
268           output_Real_def (prefix + i.key (), val);       
269         }
270       else if (dynamic_cast<int_identifier*> (i.val ()))
271         {
272           int val  = *i.val ()->access_content_int (false);       
273           
274           output_int_def (prefix + i.key (), val);        
275         }
276     }
277 }
278
279 void
280 Paper_outputter::output_version ()
281 {
282   String id_str = "Lily was here";
283   if (no_timestamps_global_b)
284     id_str += ".";
285   else
286     id_str += String (", ") + version_str ();
287
288   output_String_def ( "mudelatagline", id_str);
289   output_String_def ( "LilyPondVersion", version_str ());
290 }
291
292 void
293 Paper_outputter::start_line (Real height)
294 {
295   SCM scm = gh_list (ly_symbol ("start-line"),
296                      gh_double2scm (height),
297                      SCM_UNDEFINED);
298   output_scheme (scm);
299 }
300
301 void
302 Paper_outputter::output_font_def (int i, String str)
303 {
304   SCM scm = gh_list (ly_symbol ("font-def"),
305                      gh_int2scm (i),
306                      gh_str02scm (str.ch_l ()),
307                      SCM_UNDEFINED);
308
309   output_scheme (scm);
310 }
311
312 void
313 Paper_outputter::output_Real_def (String k, Real v)
314 {
315   
316   SCM scm = gh_list (ly_symbol ("lily-def"),
317                      gh_str02scm (k.ch_l ()),
318                      gh_str02scm (to_str(v).ch_l ()),
319                      SCM_UNDEFINED);
320   output_scheme (scm);
321
322   gh_define (k.ch_l (), gh_double2scm (v));
323 }
324
325 void
326 Paper_outputter::output_String_def (String k, String v)
327 {
328   
329   SCM scm = gh_list (ly_symbol ("lily-def"),
330                      gh_str02scm (k.ch_l ()),
331                      gh_str02scm (v.ch_l ()),
332                      SCM_UNDEFINED);
333   output_scheme (scm);
334
335   gh_define (k.ch_l (), gh_str02scm (v.ch_l ()));
336 }
337
338 void
339 Paper_outputter::output_int_def (String k, int v)
340 {
341   SCM scm = gh_list (ly_symbol ("lily-def"),
342                      gh_str02scm (k.ch_l ()),
343                      gh_str02scm (to_str (v).ch_l ()),
344                      SCM_UNDEFINED);
345   output_scheme (scm);
346
347   gh_define (k.ch_l (), gh_int2scm (v));
348 }
349
350
351
352 void
353 Paper_outputter::stop_line ()
354 {
355   SCM scm = gh_list (ly_symbol ("stop-line"), SCM_UNDEFINED);
356   output_scheme (scm);
357 }
358
359 void
360 Paper_outputter::stop_last_line ()
361 {
362   SCM scm = gh_list (ly_symbol ("stop-last-line"), SCM_UNDEFINED);
363   output_scheme (scm);
364 }