20 for i in [''] + Props.get('include')[0:]:
21 ifile = os.path.join(i,file)
22 for j in ['','.ly','.fly']:
25 this.__fd = open( jfile, 'r' )
29 sys.exit('ExitNotFound', file)
35 firstline = this.__fd.readline()
37 if re.match('% Creator: GNU LilyPond [0-9]+[.0-9]+',firstline ):
42 # Scan file for variable settings
45 """Scan source file for variable settings"""
49 ( 'language', Props.setLanguage ),
50 ( 'latexheaders', Props.setHeader ),
51 ( 'orientation', Props.setOrientation ),
52 ( 'paperpapersize', Props.setPaperZize ),
53 ( 'papertextheight', Props.setTextHeight ),
54 ( 'paperlinewidth', Props.setLineWidth ),
55 ( 'filename', Props.setFilename ),
59 line='prime the pump' # ugh
61 line=this.__fd.readline()
62 m=re.match('\\\\def\\\\mudela([\w]+){(.*)}',line)
65 if m.group(1) == var[0]:
66 var[1](m.group(2),'file')
68 for var in Props.get('titledefs'):
70 titles[var]=m.group(2)
72 Props.setTitles(titles,'file')
86 """Start the latex file"""
87 now=time.asctime(time.localtime(time.time()))
88 linewidth = Props.get('linewidth')
89 textheight = Props.get('textheight')
91 if Props.get('orientation') == 'landscape':
92 pagewidth = Props.get('pageheight')
93 pageheight = Props.get('pagewidth')
95 pageheight = Props.get('pageheight')
96 pagewidth = Props.get('pagewidth')
98 horizontalMarginArg = ( (pagewidth - linewidth)/2 )
99 verticalMarginArg = ( (pageheight - textheight)/2 )
103 %% Automatically generated from %s, %s
105 \\documentclass[%s]{article}
108 \\usepackage{geometry}
109 \\usepackage[latin1]{inputenc}
110 %%\\usepackage[T1]{fontenc}
112 %%\\addtolength{\\oddsidemargin}{-1cm}
113 %%\\addtolength{\\topmargin}{-1cm}
114 %%\\setlength{\\textwidth}{%s}
115 %%\\setlength{\\textheight}{%s}
116 \\geometry{width=%spt, left=%spt, height=%spt, top=%spt}
121 """ % ( program_id(), Props.get('filename'), now, Props.get('papersize'),
122 Props.get('language'), Props.get('pagenumber'), linewidth, textheight,
123 linewidth, horizontalMarginArg, textheight, verticalMarginArg,
124 Props.get('header') )
126 pathcomp = os.path.splitext(file)
127 this.__base = pathcomp[0]
128 this.__outfile = '%s.%d%s' % (pathcomp[0], os.getpid(), pathcomp[1])
130 this.__fd = open(this.__outfile,"w")
132 sys.exit('ExitNoWrite', this.__outfile)
134 this.__mudelaDefs('')
145 \\def\\mudelapiece{}%
147 this.__mudelaDefs("\\def")
149 \\def\\theopus{\\mudelaopus}% ugh
150 \\def\\thepiece{\\mudelapiece}%
154 def __mudelaDefs(this,opt):
155 titles = Props.get('titles')
156 for key in titles.keys():
157 this.write('%s\\mudela%s{%s}%%\n' % (opt,key,titles[key]))
160 outfile=this.__base + '.dvi'
161 if Props.get('output') != '':
162 outfile = os.path.join(Props.get('output'), outfile )
165 \\vfill\\hfill{\\LilyIdString}
169 if ( os.name == 'posix' ):
170 stat = os.system('latex \'\\nonstopmode \\input %s\'' %
172 else: # Windows shells don't eat the single quotes
173 stat = os.system('latex \\nonstopmode \\input %s' %
176 sys.exit('ExitBadLatex')
177 if os.path.isfile(outfile):
179 os.rename(this.__base + '.' + str(os.getpid()) + '.dvi', outfile)
183 def __set(this,var,value,requester):
184 if this.__overrideTable[requester] < this.__data[var][1]:
187 this.__data[var] = [value, this.__overrideTable[requester]]
190 if var == 'include' or var == 'lilyOutputFiles':
191 return this.__data[var][0][0:] # return a copy not a ref
193 return this.__data[var][0]
195 def get_texfile_path (this, var):
197 cmd =('kpsewhich tex %s 2>&1' % var)
198 pipe = os.popen (cmd, 'r')
199 path = pipe.readline ()[:-1] # chop off \n
201 path = os.path.join(this.get('root'), 'texmf', 'tex', 'lilypond', var)
207 this.__overrideTable = {
216 this.__roverrideTable = {} # reverse lookup
217 for i in this.__overrideTable.items():
218 this.__roverrideTable[i[1]]=i[0]
221 'pagewidth' : [597, this.__overrideTable['init']],
222 'pageheight' : [845, this.__overrideTable['init']],
223 'papersize' : ['a4paper', this.__overrideTable['init']],
224 'textheight' : [0, this.__overrideTable['init']],
225 'linewidth' : [0, this.__overrideTable['init']],
226 'orientation' : ['portrait', this.__overrideTable['init']],
227 'language' : ['%', this.__overrideTable['init']],
228 'include' : [[], this.__overrideTable['init']],
229 'debug' : [0, this.__overrideTable['init']],
230 'keeplilypond' : [0, this.__overrideTable['init']],
231 'keeply2dvi' : [0, this.__overrideTable['init']],
232 'pagenumber' : ['%', this.__overrideTable['init']],
233 'separate' : [0, this.__overrideTable['init']],
234 'output' : ['', this.__overrideTable['init']],
235 'header' : ['%', this.__overrideTable['init']],
236 'dependencies' : [0, this.__overrideTable['init']],
237 'root' : ['', this.__overrideTable['init']],
238 'tmp' : ['d:\tmp', this.__overrideTable['init']],
239 'filename' : ['', this.__overrideTable['init']],
240 'titledefs' : [[], this.__overrideTable['init']],
241 'titles' : [{}, this.__overrideTable['init']],
242 'lilyOutputFiles' : [[], this.__overrideTable['init']],
245 if os.environ.has_key('LILYINCLUDE'):
246 tmp=this.get('include')
247 for s in string.split(os.environ['LILYINCLUDE'],os.pathsep):
249 this.__set('include', tmp, 'environment')
251 if os.environ.has_key('LILYPOND'):
252 this.__set('root',os.environ['LILYPOND'], 'environment')
254 p=os.path.split(sys.argv[0])
255 p=os.path.split(p[0])
256 this.__set('root',p[0],'init')
259 if os.environ.has_key ('TEXINPUTS'):
260 t = os.pathsep + os.environ['TEXINPUTS']
261 os.environ['TEXINPUTS'] = os.path.join(this.get('root'), 'texmf',
262 'tex', 'lilypond' ) + t
264 if os.environ.has_key('TMP'):
265 this.__set('tmp',os.environ['TMP'],'environment')
267 if not os.environ.has_key('HOME'):
268 if os.environ.has_key('HOMEDRIVE') and \
269 os.environ.has_key('HOMEPATH'):
270 os.environ['HOME'] = os.environ['HOMEDRIVE'] + \
271 os.environ['HOMEPATH']
273 os.environ['HOME'] = os.curdir
276 fd =this.get_texfile_path ('titledefs.tex')
278 line='prime the pump' # ugh
281 m=re.match('\\\\newcommand\*{\\\\mudela([\w]+)}',line)
283 mudefs.append(m.group(1))
285 this.__set('titledefs', mudefs, 'init')
295 ( 'LILYPOND', this.setInclude ),
296 ( 'LANGUAGE', this.setLanguage ),
297 ( 'LATEXHF', this.setHeader ),
298 ( 'ORIENTATION', this.setOrientation ),
299 ( 'OUTPUTDIR', this.setOutput ),
300 ( 'PAPERSIZE', this.setPaperZize ),
301 ( 'PHEIGHT', this.setTextHeight ),
302 ( 'TMP', this.setTmp ),
303 ( 'PWIDTH', this.setLineWidth ),
306 for d in [os.path.join(this.get('root'),'share','lilypond'), \
307 os.environ['HOME'], os.curdir ]:
308 file=os.path.join(d,'.lilyrc')
310 fd = open( file, 'r' )
314 line='prime the pump' # ugh
317 if re.match('#.*',line):
319 m=re.search('([\w]+)=(.*)',line)
322 if m.group(1) == var[0]:
323 var[1](m.group(2),'rcfile')
330 def setPaperZize(this,size,requester):
332 # regex width height name
333 # ----- ----- ------ ----
334 ( 'a0.*', 2389, 3381, 'a0paper' ),
335 ( 'a1$|a1p.*', 1690, 2389, 'a1paper' ),
336 ( 'a2.*', 1194, 1690, 'a2paper' ),
337 ( 'a3.*', 845, 1194, 'a3paper' ),
338 ( 'a4.*', 597, 845, 'a4paper' ),
339 ( 'a5.*', 423, 597, 'a5paper' ),
340 ( 'a6.*', 298, 423, 'a6paper' ),
341 ( 'a7.*', 211, 298, 'a7paper' ),
342 ( 'a8.*', 305, 211, 'a8paper' ),
343 ( 'a9.*', 105, 305, 'a9paper' ),
344 ( 'a10.*', 74, 105, 'a10paper' ),
345 ( 'b0.*', 2847, 4023, 'b0paper' ),
346 ( 'b1.*', 2012, 2847, 'b1paper' ),
347 ( 'b2.*', 1423, 2012, 'b2paper' ),
348 ( 'b3.*', 1006, 1423, 'b3paper' ),
349 ( 'b4.*', 712, 1006, 'b4paper' ),
350 ( 'b5.*', 503, 712, 'b5paper' ),
351 ( 'archA$', 650, 867, 'archApaper' ),
352 ( 'archB$', 867, 1301, 'archBpaper' ),
353 ( 'archC$', 1301, 1734, 'archCpaper' ),
354 ( 'archD$', 1734, 2602, 'archDpaper' ),
355 ( 'archE$', 2602, 3469, 'archEpaper' ),
356 ( 'flsa$|flse$', 614, 940, 'flsapaper' ),
357 ( 'halfletter$', 397, 614, 'halfletterpaper' ),
358 ( 'ledger$', 1229, 795, 'ledgerpaper' ),
359 ( 'legal$', 614, 1012, 'legalpaper' ),
360 ( 'letter$', 614, 795, 'letterpaper' ),
361 ( 'note$', 542, 723, 'notepaper' )
365 for paper in paperTable:
366 if re.match(paper[0],size):
368 this.__set('pagewidth',paper[1],requester)
369 this.__set('pageheight',paper[2],requester)
370 this.__set('papersize',paper[3],requester)
374 sys.exit('ExitBadPaper',size)
379 def setTextHeight(this,size,requester):
380 m=re.match('([0-9][.0-9]*)(cm|mm|pt|$)',size)
382 if m.group(2) == 'cm':
383 this.__set('textheight',\
384 float(m.group(1)) * 72.27/2.54, requester )
385 elif m.group(2) == 'mm':
386 this.__set('textheight',\
387 float(m.group(1)) * 72.27/25.4, requester )
388 elif m.group(2) == 'pt':
389 this.__set('textheight', float(m.group(1)), requester )
390 elif m.group(2) == '':
391 this.__set('textheight', float(m.group(1)), requester )
393 sys.exit('ExitBadHeight', m.group(2))
395 sys.exit('ExitBadHeight', size)
399 def setLineWidth(this,size,requester):
400 m=re.match('([0-9][.0-9]*)(cm|mm|pt|$)',size)
402 if m.group(2) == 'cm':
403 this.__set('linewidth', \
404 float(m.group(1)) * 72.27/2.54, requester )
405 elif m.group(2) == 'mm':
406 this.__set('linewidth', \
407 float(m.group(1)) * 72.27/25.4, requester )
408 elif m.group(2) == 'pt':
409 this.__set('linewidth', float(m.group(1)), requester )
410 elif m.group(2) == '':
411 this.__set('linewidth', float(m.group(1)), requester )
413 sys.exit('ExitBadWidth', m.group(2))
415 sys.exit('ExitBadWidth', size)
419 def setOrientation(this,orient,requester):
420 if orient == 'landscape' or orient == 'portrait':
421 this.__set('orientation', orient, requester )
423 sys.exit('ExitBadOrient', orient)
427 def setLanguage(this,lang,requester):
428 this.__set('language', '\\usepackage[%s]{babel}' % (lang), requester )
432 def setInclude(this,inc, requester):
433 tmp = this.get('include')
435 this.__set('include', tmp, requester )
439 def setDebug(this,requester):
440 this.__set('debug',1,requester)
445 def clearDebug(this, requester):
446 this.__set('debug',0,requester)
448 # Set Keeplilypond flag
450 def setKeeplilypond(this, requester):
451 this.__set('keeplilypond',1,requester)
454 # Clear Keeplilypond flag
456 def clearKeeplilypond(this, requester):
457 this.__set('keeplilypond',0,requester)
460 # Set Keeply2dvi flag
462 def setKeeply2dvi(this, requester):
463 this.__set('keeply2dvi',1,requester)
465 # Clear Keeply2dvi flag
467 def clearKeeply2dvi(this, requester):
468 this.__set('keeply2dvi',0,requester)
470 # Set No page number flag
472 def setNonumber(this, requester):
473 this.__set('pagenumber','\\pagestyle{empty}',requester)
476 # Clear No page number flag
478 def clearNonumber(this, requester):
479 this.__set('pagenumber','%',requester)
483 def setSeparate(this, requester):
484 this.__set('separate',1,requester)
487 # Clear separate flag
489 def clearSeparate(this, requester):
490 this.__set('separate',0,requester)
493 # Set output directory name
495 def setOutput(this,out,requester):
496 this.__set('output',out,requester)
499 # Set latex header name
501 def setHeader(this,head, requester):
502 this.__set('header',head,requester)
504 # Set Dependencies flag to generate makefile dependencies
506 def setDependencies(this, requester):
507 this.__set('dependencies',1,requester)
510 # Clear Dependencies flag
512 def clearDependencies(this, requester):
513 this.__set('dependencies',0,requester)
517 def setTmp(this,dir, requester):
518 this.__set('tmp',dir,requester)
520 # Set mudela source file name
522 def setFilename(this,file, requester):
523 this.__set('filename',file,requester)
527 def setTitles(this,titles, requester):
528 this.__set('titles',titles,requester)
530 def addLilyOutputFiles(this,file,requester):
531 tmp = this.get('lilyOutputFiles')
533 this.__set('lilyOutputFiles',tmp,requester)
535 def printProps(this):
536 for key in this.__data.keys():
537 print "%s <%s>:<%s>" % (key,this.get(key),
538 this.__roverrideTable[this.__data[key][1]])
542 if len(Props.get('include')) > 0:
543 inc = '-I ' + string.join(Props.get('include'),os.pathsep)
546 if Props.get('dependencies'):
553 def writeLilylog(contents):
554 if Props.get('keeplilypond'):
555 file='lilylog.' + str(os.getpid())
556 output = Props.get('output')
558 file = os.path.join( output, file )
560 fd = open( file, 'w' )
562 sys.exit('ExitNoWrite', file)
566 def getTeXFile(contents):
567 m = re.search('^TeX output to (.+)\.tex', contents,re.M)
569 return ( m.group(1)+'.tex' )
571 sys.exit('ExitNoTeXName')
574 return name + ' ' + version;
579 return os.environ['MAILADDRESS']
581 return '(address unknown)'
585 sys.stderr.write (program_id () + '\n')
589 'Generate dvi file from mudela or lilypond output\n'
590 'Usage: ' + name + ' [OPTION]... [FILE]...\n'
593 ' -D,--debug increase verbosity\n'
594 ' -F,--headers= name of additional LaTeX headers file\n'
595 ' -H,--Height= set paper height (points) (see manual page)\n'
596 ' -I,--include=DIR add DIR to LilyPond\'s search path\n'
597 ' -K,--keeplilypond keep lilypond output files\n'
598 ' -L,--landscape set landscape orientation\n'
599 ' -N,--nonumber switch off page numbering\n'
600 ' -O,--orientation= set orientation (obsolete - use -L instead)\n'
601 ' -W,--Width= set paper width (points) (see manual page)\n'
602 ' -d,--dependencies tell lilypond make a dependencies file\n'
603 ' -h,--help this help text\n'
604 ' -k,--keeply2dvi keep ly2dvi output files\n'
605 ' -l,--language= give LaTeX language (babel)\n'
606 ' -o,--output= set output directory\n'
607 ' -p,--papersize= give LaTeX papersize (eg. a4)\n'
608 ' -s,--separate run all files separately through LaTeX\n'
610 'files may be (a mix of) input to or output from lilypond(1)\n'
615 """Generate dvi files from lilypond source/output"""
618 outfile = TeXOutput()
622 (options, files) = getopt.getopt (sys.argv[1:],
623 'DF:H:I:KLNW:dhkl:o:p:s',
624 ['debug', 'headers=', 'Height=',
625 'include=', 'keeplilypond', 'landscape',
626 'nonumber', 'Width=', 'dependencies',
627 'help', 'keeply2dvi', 'language=',
628 'output=', 'papersize=', 'separate'])
632 if o == '--debug' or o == '-D':
633 Props.setDebug('commandline')
634 elif o == '--headers' or o == '-F':
635 Props.setHeader(a,'commandline')
636 elif o == '--include' or o == '-I':
637 Props.setInclude(a,'commandline')
638 elif o == '--Height' or o == '-H':
639 Props.setTextHeight(a,'commandline')
640 elif o == '--keeplilypond' or o == '-K':
641 Props.setKeeplilypond('commandline')
642 elif o == '--landscape' or o == '-L':
643 Props.setOrientation('landscape','commandline')
644 elif o == '--nonumber' or o == '-N':
645 Props.setNonumber('commandline')
646 elif o == '--Width' or o == '-W':
647 Props.setLineWidth(a,'commandline')
648 elif o == '--dependencies' or o == '-d':
649 Props.setDependencies('commandline')
650 elif o == '--help' or o == '-h':
653 elif o == '--keeply2dvi' or o == '-k':
654 Props.setKeeply2dvi('commandline')
655 elif o == '--language' or o == '-l':
656 Props.setLanguage(a,'commandline')
657 elif o == '--output' or o == '-o':
658 Props.setOutput(a,'commandline')
659 elif o == '--papersize' or o == '-p':
660 Props.setPaperZize(a,'commandline')
661 elif o == '--separate' or o == '-s':
662 Props.setSeparate('commandline')
670 cmd = 'lilypond %s %s 2>&1' % (getLilyopts(), file)
671 fd = os.popen( cmd , 'r' )
676 sys.exit('ExitBadLily', cmd )
677 texFile=getTeXFile(log)
679 Props.addLilyOutputFiles(texFile,'program')
680 texInputFiles.append(texFile)
682 texInputFiles.append(file)
685 for file in texInputFiles:
687 infile.setVars() # first pass set variables
697 if Props.get('separate'):
701 if not Props.get('separate'):
705 sys.exit('ExitBadArgs','No files specified')
711 'ExitInterupt' : ['Ouch!', 1 ],
712 'ExitBadArgs' : ['Wrong number of arguments', 2 ],
713 'ExitNotFound' : ['File not found', 3 ],
714 'ExitBadPaper' : ['Unknown papersize', 4 ],
715 'ExitBadHeight' : ['Invalid Height specification', 5 ],
716 'ExitBadWidth' : ['Invalid Width specification', 6 ],
717 'ExitBadOrient' : ['Invalid Orientation specification', 7 ],
718 'ExitNoWrite' : ['Permission denied', 8 ],
719 'ExitNoTeXName' : ['hmm, I could not find an output file name', 9 ],
720 'ExitBadLily' : ['Lilypond failed', 10 ],
721 'ExitBadLatex' : ['Latex failed', 11 ],
722 'ExitUnknown' : ['Unknown Exit Code', 20 ],
728 if not Props.get('keeplilypond'):
729 lilyfiles = Props.get('lilyOutputFiles')
730 if not Props.get('keeply2dvi'):
731 tmpfiles = glob.glob('*.' + str(os.getpid()) + '.*' )
732 for file in lilyfiles + tmpfiles:
733 if os.path.isfile(file):
748 except KeyboardInterrupt:
749 print ExitTable['ExitInterupt'][0]
751 sys.exit(ExitTable['ExitInterupt'][1])
753 except SystemExit, errno:
754 if ExitTable.has_key(errno.args[0]):
755 msg = ExitTable[errno.args[0]]
757 msg = ExitTable['ExitUnknown']
758 if len(errno.args) > 1:
759 sys.stderr.write( '%s: %s: %s\n' % (name, msg[0], errno.args[1]))
761 sys.stderr.write( '%s %s\n' % (name, msg[0]))