#!@PYTHON@
# vim: set noexpandtab:
# TODO:
-# * Figure out clean set of options. Hmm, isn't it pretty ok now?
-# * add support for .lilyrc
+# * junk --outdir for --output
+# * Figure out clean set of options.
+# *
# * EndLilyPondOutput is def'd as vfil. Causes large white gaps.
# * texinfo: add support for @pagesize
# geometry.sty and article.cls. Give me a hint, and I'll
# fix it.)
+#
+# TODO: magnification support should also work for texinfo -> html: eg. add as option to dvips.
+#
+
# This is was the idea for handling of comments:
# Multiline comments, @ignore .. @end ignore is scanned for
# in read_doc_file, and the chunks are marked as 'ignore', so
# The the rest of the rexeces are searched for. They don't have to test
# if they are on a commented out line.
+
+
import os
import stat
import string
program_version = '@TOPLEVEL_VERSION@'
if program_version == '@' + 'TOPLEVEL_VERSION' + '@':
- program_version = '1.3.113'
+ program_version = '1.5.18'
+
+#
+# Try to cater for bad installations of LilyPond, that have
+# broken TeX setup. Just hope this doesn't hurt good TeX
+# setups. Maybe we should check if kpsewhich can find
+# feta16.{afm,mf,tex,tfm}, and only set env upon failure.
+#
+datadir = '@datadir@'
+environment = {
+ 'MFINPUTS' : datadir + '/mf:',
+ 'TEXINPUTS': datadir + '/tex:' + datadir + '/ps:.:',
+ 'TFMFONTS' : datadir + '/tfm:',
+ 'GS_FONTPATH' : datadir + '/afm:' + datadir + '/pfa',
+ 'GS_LIB' : datadir + '/ps',
+}
+
+def setup_environment ():
+ for key in environment.keys ():
+ val = environment[key]
+ if os.environ.has_key (key):
+ val = val + os.pathsep + os.environ[key]
+ os.environ[key] = val
+
+
include_path = [os.getcwd()]
elif name[-5:] == 'paper':
self.m_papersize = name
else:
- self._set_dimen('m_geo_'+name, value)
+ pass
+ # what is _set_dimen ?? /MB
+ #self._set_dimen('m_geo_'+name, value)
def __setattr__(self, name, value):
if type(value) == type("") and \
dimension_conversion_dict.has_key (value[-2:]):
- f = dimension_conversion_dict[dim]
+ f = dimension_conversion_dict[value[-2:]]
self.__dict__[name] = f(float(value[:-2]))
else:
self.__dict__[name] = value
if not self.m_use_geometry:
return latex_linewidths[self.m_papersize][self.m_fontsize]
else:
- geo_opts = (a == None, b == None, c == None)
-
+ geo_opts = (self.m_geo_lmargin == None,
+ self.m_geo_width == None,
+ self.m_geo_rmargin == None)
+
if geo_opts == (1, 1, 1):
if self.m_geo_textwidth:
return self.m_geo_textwidth
'output-default-pre': "\\def\preLilypondExample{}\n",
'usepackage-graphics': '\\usepackage{graphics}\n',
'output-eps': '\\noindent\\parbox{\\lilypondepswidth{%(fn)s.eps}}{\includegraphics{%(fn)s.eps}}',
- 'output-tex': '\\preLilypondExample \\input %(fn)s.tex \\postLilypondExample\n',
+ 'output-tex': '{\\preLilypondExample \\input %(fn)s.tex \\postLilypondExample\n}',
'pagebreak': r'\pagebreak',
},
'texi' : {'output-lilypond': """@lilypond[%s]
@end tex
@html
<p>
-<img src=%(fn)s.png>
+<a href="%(fn)s.png">
+<img border=0 src="%(fn)s.png" alt="[picture of music]">
+</a>
@end html
""",
}
re_dict = {
'latex': {'input': r'(?m)^[^%\n]*?(?P<match>\\mbinput{?([^}\t \n}]*))',
'include': r'(?m)^[^%\n]*?(?P<match>\\mbinclude{(?P<filename>[^}]+)})',
- 'option-sep' : ', *',
+ 'option-sep' : ',\s*',
'header': r"\\documentclass\s*(\[.*?\])?",
'geometry': r"^(?m)[^%\n]*?\\usepackage\s*(\[(?P<options>.*)\])?\s*{geometry}",
'preamble-end': r'(?P<code>\\begin{document})',
'verbatim': r"(?s)(?P<code>\\begin{verbatim}.*?\\end{verbatim})",
'verb': r"(?P<code>\\verb(?P<del>.).*?(?P=del))",
- 'lilypond-file': r'(?m)^[^%\n]*?(?P<match>\\lilypondfile(\[(?P<options>.*?)\])?\{(?P<filename>.+)})',
- 'lilypond' : r'(?m)^[^%\n]*?(?P<match>\\lilypond(\[(?P<options>.*?)\])?{(?P<code>.*?)})',
- 'lilypond-block': r"(?sm)^[^%\n]*?(?P<match>\\begin(\[(?P<options>.*?)\])?{lilypond}(?P<code>.*?)\\end{lilypond})",
+ 'lilypond-file': r'(?m)^[^%\n]*?(?P<match>\\lilypondfile\s*(\[(?P<options>.*?)\])?\s*\{(?P<filename>.+)})',
+ 'lilypond' : r'(?m)^[^%\n]*?(?P<match>\\lilypond\s*(\[(?P<options>.*?)\])?\s*{(?P<code>.*?)})',
+ 'lilypond-block': r"(?sm)^[^%\n]*?(?P<match>\\begin\s*(\[(?P<options>.*?)\])?\s*{lilypond}(?P<code>.*?)\\end{lilypond})",
'def-post-re': r"\\def\\postLilypondExample",
'def-pre-re': r"\\def\\preLilypondExample",
'usepackage-graphics': r"\usepackage{graphics}",
'lilypond-file': '(?m)^(?!@c)(?P<match>@lilypondfile(\[(?P<options>.*?)\])?{(?P<filename>[^}]+)})',
'lilypond' : '(?m)^(?!@c)(?P<match>@lilypond(\[(?P<options>.*?)\])?{(?P<code>.*?)})',
'lilypond-block': r"""(?m)^(?!@c)(?P<match>(?s)(?P<match>@lilypond(\[(?P<options>.*?)\])?\s(?P<code>.*?)@end lilypond\s))""",
- 'option-sep' : ', *',
+ 'option-sep' : ',\s*',
'intertext': r',?\s*intertext=\".*?\"',
'multiline-comment': r"(?sm)^\s*(?!@c\s+)(?P<code>@ignore\s.*?@end ignore)\s",
'singleline-comment': r"(?m)^.*?(?P<match>(?P<code>@c.*$\n+))",
else:
return (0,0)
-
def error (str):
sys.stderr.write (str + "\n Exiting ... \n\n")
raise 'Exiting.'
is_fragment = 1
if 'fragment' in opts:
is_fragment = 1
- if 'nonfragment' in opts:
+ if 'nofragment' in opts:
is_fragment = 0
if is_fragment and not 'multiline' in opts:
l = -1.0;
else:
l = __main__.paperguru.get_linewidth()
-
- if 'relative' in opts:#ugh only when is_fragment
- body = '\\relative c { %s }' % body
+
+ for o in opts:
+ m= re.search ('relative(.*)', o)
+ v = 0
+ if m:
+ try:
+ v = string.atoi (m.group (1))
+ except ValueError:
+ pass
+
+ v = v + 1
+ pitch = 'c'
+ if v < 0:
+ pitch = pitch + '\,' * v
+ elif v > 0:
+ pitch = pitch + '\'' * v
+
+ body = '\\relative %s { %s }' %(pitch, body)
if is_fragment:
body = r"""\score {
optstring = re.sub ('\n', ' ', optstring)
body = r"""
%% Generated automatically by: lilypond-book.py
-%% options are %s %%ughUGH not original options
+%% options are %s
\include "paper%d.ly"
-\paper { linewidth = %f \pt; }
+\paper { linewidth = %f \pt }
""" % (optstring, music_size, l) + body
+
+ # ughUGH not original options
return body
def parse_options_string(s):
idx = idx + 1
continue
m = get_re ('header').match(chunks[idx][1])
- options = re.split (',[\n \t]*', m.group(1)[1:-1])
+ if m.group (1):
+ options = re.split (',[\n \t]*', m.group(1)[1:-1])
+ else:
+ options = []
for o in options:
if o == 'landscape':
paperguru.m_landscape = 1
return newchunks
-def find_eps_dims (match):
- "Fill in dimensions of EPS files."
-
- fn =match.group (1)
- dims = bounding_box_dimensions (fn)
- if g_outdir:
- fn = os.path.join(g_outdir, fn)
-
- return '%ipt' % dims[0]
-
def system (cmd):
sys.stderr.write ("invoking `%s'\n" % cmd)
error ('Error command exited with value %d\n' % st)
return st
+
+def get_bbox (filename):
+ f = open (filename)
+ gr = []
+ while 1:
+ l =f.readline ()
+ m = re.match ('^%%BoundingBox: ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)', l)
+ if m:
+ gr = map (string.atoi, m.groups ())
+ break
+
+ return gr
+
+def make_pixmap (name):
+ bbox = get_bbox (name + '.eps')
+ margin = 3
+ fo = open (name + '.trans.eps' , 'w')
+ fo.write ('%d %d translate\n' % (-bbox[0]+margin, -bbox[1]+margin))
+ fo.close ()
+
+ res = 90
+
+ x = (2* margin + bbox[2] - bbox[0]) * res / 72.
+ y = (2* margin + bbox[3] - bbox[1]) * res / 72.
+
+ cmd = r"""gs -g%dx%d -sDEVICE=pgm -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=- -r%d -dNOPAUSE %s %s -c quit | pnmtopng > %s"""
+
+ cmd = cmd % (x, y, res, name + '.trans.eps', name + '.eps',name + '.png')
+ try:
+ status = system (cmd)
+ except:
+ os.unlink (name + '.png')
+ error ("Removing output file")
+
def compile_all_files (chunks):
+ global foutn
eps = []
tex = []
png = []
x = os.path.join (g_here_dir, x)
return ' -I %s' % x
- incs = map (incl_opt, include_path)
+ incs = map (incl_opt, include_path)
lilyopts = string.join (incs, ' ' )
- texfiles = string.join (tex, ' ')
if do_deps:
lilyopts = lilyopts + ' --dependencies '
- #system ('touch %s' % texfiles)
+ if g_outdir:
+ lilyopts = lilyopts + '--dep-prefix=' + g_outdir + '/'
+ texfiles = string.join (tex, ' ')
system ('lilypond --header=texidoc %s %s' % (lilyopts, texfiles))
#
- # Ugh, fixing up dependencies for outdir/ and .tex generation
+ # Ugh, fixing up dependencies for .tex generation
#
if do_deps:
depfiles=map (lambda x: re.sub ('(.*)\.ly', '\\1.dep', x), tex)
for i in depfiles:
- text=open (i).read ()
- text=re.sub ('\n([^:\n]*):', '\n' + g_outdir + '/' + foutn + ':', text)
- text=re.sub (' ([^ /\n]*).ly', ' ' + g_outdir + '/\\1.ly', text)
- open (i, 'w').write (text)
+ f =open (i)
+ text=f.read ()
+ f.close ()
+ text=re.sub ('\n([^:\n]*):', '\n' + foutn + ':', text)
+ f = open (i, 'w')
+ f.write (text)
+ f.close ()
for e in eps:
system(r"tex '\nonstopmode \input %s'" % e)
system(r"dvips -E -o %s %s" % (e + '.eps', e))
+
for g in png:
- cmd = r"""gs -sDEVICE=pgm -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=- -r90 -dNOPAUSE %s -c quit | pnmcrop | pnmtopng > %s"""
- cmd = cmd % (g + '.eps', g + '.png')
- system (cmd)
- if g_outdir:
- os.chdir(d)
+ make_pixmap (g)
+
+ os.chdir (d)
def update_file (body, name):
def write_deps (fn, target, chunks):
global read_files
- sys.stdout.write('writing `%s\'\n' % os.path.join(g_outdir, fn))
+ sys.stdout.write('Writing `%s\'\n' % os.path.join(g_outdir, fn))
f = open (os.path.join(g_outdir, fn), 'w')
f.write ('%s%s: ' % (g_dep_prefix, target))
for d in read_files:
for d in basenames:
if g_outdir:
d=g_outdir + '/' + d
+ if g_dep_prefix:
+ #if not os.isfile (d): # thinko?
+ if not re.search ('/', d):
+ d = g_dep_prefix + d
f.write ('%s.tex ' % d)
f.write ('\n')
#if len (basenames):
n.append (c)
return n
+
+## what's this? Docme --hwn
+##
def fix_epswidth (chunks):
newchunks = []
for c in chunks:
- if c[0] == 'lilypond' and 'eps' in c[2]:
- body = re.sub (r"""\\lilypondepswidth{(.*?)}""", find_eps_dims, c[1])
- newchunks.append(('lilypond', body, c[2], c[3], c[4]))
- else:
+ if c[0] <> 'lilypond' or 'eps' not in c[2]:
newchunks.append (c)
+ continue
+
+ mag = 1.0
+ for o in c[2]:
+ m = re.match ('magnification=([0-9.]+)', o)
+ if m:
+ mag = string.atof (m.group (1))
+
+ def replace_eps_dim (match, lmag = mag):
+ filename = match.group (1)
+ dims = bounding_box_dimensions (filename)
+
+ return '%fpt' % (dims[0] *lmag)
+
+ body = re.sub (r"""\\lilypondepswidth{(.*?)}""", replace_eps_dim, c[1])
+ newchunks.append(('lilypond', body, c[2], c[3], c[4]))
+
return newchunks
+foutn=""
def do_file(input_filename):
global foutn
file_settings = {}
scan_preamble(chunks)
chunks = process_lilypond_blocks(my_outname, chunks)
+ foutn = os.path.join (g_outdir, my_outname + '.' + format)
+
# Do It.
if __main__.g_run_lilypond:
compile_all_files (chunks)
x = 0
chunks = completize_preamble (chunks)
- foutn = os.path.join(g_outdir, my_outname + '.' + format)
sys.stderr.write ("Writing `%s'\n" % foutn)
fout = open (foutn, 'w')
for c in chunks:
error ("outdir is a file: %s" % g_outdir)
if not os.path.exists(g_outdir):
os.mkdir(g_outdir)
+setup_environment ()
for input_filename in files:
do_file(input_filename)