4 # Pythonic interface to LilyPond call.
16 ################################################################
19 def file_is_newer (f1
, f2
):
20 return os
.stat (f1
).st_mtime
> os
.stat (f2
).st_mtime
22 def writable_directory (dir):
25 testfile
= os
.path
.join (dir,".testwrite")
26 f
= open (testfile
, 'w')
34 def quote_quotes (str):
35 return re
.sub ('"', '\\"', str)
38 ################################################################
41 def check_fontconfig (appdir
):
42 prefix
= appdir
+ '/Contents/Resources'
43 my_sysfont_dir
= prefix
+ '/share/SystemFonts'
44 sysfont_dir
= '/System/Library/Fonts'
46 fc_cache
= (prefix
+ '/font.cache-1')
47 local_fc_conf
= open (prefix
+ '/etc/fonts/local.conf','w')
48 local_fc_conf
.write ('''<?xml version="1.0"?>
49 <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
50 <!-- /etc/fonts/local.conf file for local customizations -->
54 </fontconfig>''' % (appdir
+ '/Contents/Resources/share/fonts/', fc_cache
))
56 need_update
= not os
.path
.exists (fc_cache
)
58 open (fc_cache
, 'w').write ('')
64 p
= os
.environ
['DYLD_LIBRARY_PATH']
71 env
['DYLD_LIBRARY_PATH'] = prefix
+ '/lib' + ':' + p
72 env
['FONTCONFIG_PATH'] = prefix
+ '/etc/fonts/'
73 env
['GS_LIB'] = prefix
+ '/share/ghostscript/8.15/lib/'
74 env
['GUILE_LOAD_PATH'] = prefix
+ '/share/guile/1.6'
75 env
['LILYPOND_DATADIR'] = prefix
+ '/share/lilypond/current'
76 env
['PANGO_RC_FILE'] = prefix
+ '/etc/pango/pangorc'
77 env
['HOME'] = os
.environ
['HOME']
78 env
['PATH'] = prefix
+ '/bin/' + ':' + os
.environ
['PATH']
79 env
['PANGO_PREFIX'] = prefix
83 def get_gui_command_line (appdir
, args
):
88 if a
[0] not in ['-','/']:
89 a
= os
.path
.join (cwd
, a
)
93 def get_dest_dir (arguments
):
95 dest_dir
= os
.environ
['LILYPOND_DESTDIR']
100 if (not dest_dir
and a
and a
[0] == '/'):
101 dest_dir
= os
.path
.split (a
)[0]
104 if not dest_dir
or not writable_directory (dest_dir
):
105 dest_dir
= os
.environ
['HOME']+ '/Desktop'
109 ################################################################
113 def check_app_dir (self
, dir):
114 self
.error_string
= ''
115 if not writable_directory (dir):
116 self
.error_string
= ('Cannot write program directory\n'
117 + 'This program must be installed before using.')
120 self
.error_string
= ("Application directory should be absolute. "
124 def __init__ (self
, appdir
, args
):
125 self
.check_app_dir (appdir
)
126 if self
.error_string
:
130 self
.env
= get_env (appdir
+ '/Contents/Resources')
131 self
.executable
= appdir
+ '/Contents/Resources/bin/lilypond'
132 self
.args
= [self
.executable
] + args
135 self
.need_fc_update
= check_fontconfig (appdir
)
136 self
.reroute_output
= False
138 def set_gui_options (self
):
139 self
.args
= ([self
.args
[0]]
140 + get_gui_command_line (self
.appdir
, self
.args
[1:]))
142 self
.cwd
= get_dest_dir (self
.args
[1:])
143 self
.reroute_output
= 1
145 def print_env (self
):
146 for (k
,v
) in self
.env
.items ():
147 print 'export %s="%s"' % (k
,v
)
149 def get_process (self
, executable
, args
):
152 if self
.reroute_output
:
153 out
= subprocess
.PIPE
154 err
= subprocess
.STDOUT
159 print 'executable: ', executable
161 self
.args
[0] = os
.path
.split (self
.args
[0])[1]
162 process
= subprocess
.Popen (args
,
163 executable
= executable
,
172 def get_lilypond_process (self
):
173 return self
.get_process (self
.executable
, self
.args
)
178 pdf
= os
.path
.splitext (a
)[0] + '.pdf'
179 if os
.path
.exists (pdf
):
184 # data - for callbacks.
185 def open_pdfs (self
, data
= None):
186 pdfs
= self
.get_pdfs ()
191 print 'invoking ', args
192 os
.spawnv (os
.P_NOWAIT
, b
, [b
] + pdfs
)
194 ################################################################
195 # default: wrap a LP call, open PDFs.
197 if __name__
== '__main__':
198 invocation
= sys
.argv
[0]
199 appdir_dir
= sys
.argv
[1]
203 if '--debug' in argv
:
205 argv
.remove ('--debug')
207 call
= Call (appdir_dir
, argv
)
209 if call
.error_string
:
210 sys
.stderr
.write (call
.error_string
)
213 if call
.need_fc_update
:
214 sys
.stderr
.write ('Rebuilding font cache\nThis may take a few minutes.')
216 p
= call
.get_lilypond_process ()
219 if not sys
.stdin
.isatty (): # GUI