default_music_fontsize = 16
default_text_fontsize = 12
+paperguru = None
-
+# this code is ugly. It should be cleaned
class LatexPaper:
def __init__(self):
self.m_paperdef = {
- # the dimentions are from geometry.sty
+ # the dimensions are from geometry.sty
'a0paper': (mm2pt(841), mm2pt(1189)),
'a1paper': (mm2pt(595), mm2pt(841)),
'a2paper': (mm2pt(420), mm2pt(595)),
def set_geo_option(self, name, value):
if name == 'body' or name == 'text':
if type(value) == type(""):
- self._set_dimen('m_geo_textwidth', value)
+ self.m_geo_textwidth = value
else:
- self._set_dimen('m_geo_textwidth', value[0])
+ self.m_geo_textwidth = value[0]
self.__body = 1
elif name == 'portrait':
self.m_geo_landscape = 0
if self.m_geo_includemp == None:
self.m_geo_includemp = 1
elif name == 'marginparwidth' or name == 'marginpar':
- self._set_dimen('m_geo_x_marginparwidth', value)
+ self.m_geo_x_marginparwidth = value
self.m_geo_includemp = 1
elif name == 'marginparsep':
- self._set_dimen('m_geo_x_marginparsep', value)
+ self.m_geo_x_marginparsep = value
self.m_geo_includemp = 1
elif name == 'scale':
if type(value) == type(""):
elif name == 'hscale':
self.m_geo_width = self.get_paperwidth() * float(value)
elif name == 'left' or name == 'lmargin':
- self._set_dimen('m_geo_lmargin', value)
+ self.m_geo_lmargin = value
elif name == 'right' or name == 'rmargin':
- self._set_dimen('m_geo_rmargin', value)
+ self.m_geo_rmargin = value
elif name == 'hdivide' or name == 'divide':
if value[0] not in ('*', ''):
- self._set_dimen('m_geo_lmargin', value[0])
+ self.m_geo_lmargin = value[0]
if value[1] not in ('*', ''):
- self._set_dimen('m_geo_width', value[1])
+ self.m_geo_width = value[1]
if value[2] not in ('*', ''):
- self._set_dimen('m_geo_rmargin', value[2])
+ self.m_geo_rmargin = value[2]
elif name == 'hmargin':
if type(value) == type(""):
- self._set_dimen('m_geo_lmargin', value)
- self._set_dimen('m_geo_rmargin', value)
+ self.m_geo_lmargin = value
+ self.m_geo_rmargin = value
else:
- self._set_dimen('m_geo_lmargin', value[0])
- self._set_dimen('m_geo_rmargin', value[1])
+ self.m_geo_lmargin = value[0]
+ self.m_geo_rmargin = value[1]
elif name == 'margin':#ugh there is a bug about this option in
# the geometry documentation
if type(value) == type(""):
- self._set_dimen('m_geo_lmargin', value)
- self._set_dimen('m_geo_rmargin', value)
+ self.m_geo_lmargin = value
+ self.m_geo_rmargin = value
else:
- self._set_dimen('m_geo_lmargin', value[0])
- self._set_dimen('m_geo_rmargin', value[0])
+ self.m_geo_lmargin = value[0]
+ self.m_geo_rmargin = value[0]
elif name == 'total':
if type(value) == type(""):
- self._set_dimen('m_geo_width', value)
+ self.m_geo_width = value
else:
- self._set_dimen('m_geo_width', value[0])
+ self.m_geo_width = value[0]
elif name == 'width' or name == 'totalwidth':
- self._set_dimen('m_geo_width', value)
+ self.m_geo_width = value
elif name == 'paper' or name == 'papername':
self.m_papersize = value
elif name[-5:] == 'paper':
self.m_papersize = name
else:
self._set_dimen('m_geo_'+name, value)
- def _set_dimen(self, name, value):
- if type(value) == type("") and value[-2:] == 'pt':
- self.__dict__[name] = float(value[:-2])
- elif type(value) == type("") and value[-2:] == 'mm':
- self.__dict__[name] = mm2pt(float(value[:-2]))
- elif type(value) == type("") and value[-2:] == 'cm':
- self.__dict__[name] = 10 * mm2pt(float(value[:-2]))
- elif type(value) == type("") and value[-2:] == 'in':
- self.__dict__[name] = in2pt(float(value[:-2]))
+ def __setattr__(self, name, value):
+ if type(value) == type("") and \
+ dimension_conversion_dict.has_key (value[-2:]):
+ f = dimension_conversion_dict[dim]
+ self.__dict__[name] = f(float(value[:-2]))
else:
self.__dict__[name] = value
- def display(self):
- print "LatexPaper:\n-----------"
+
+ def __str__(self):
+ s = "LatexPaper:\n-----------"
for v in self.__dict__.keys():
if v[:2] == 'm_':
- print v, self.__dict__[v]
- print "-----------"
+ s = s + str (v) + ' ' + str (self.__dict__[v])
+ s = s + "-----------"
+ return s
+
def get_linewidth(self):
w = self._calc_linewidth()
if self.m_num_cols == 2:
mp = mp + self.m_geo_x_marginparwidth
else:
mp = mp + self.m_geo_marginparwidth[self.m_fontsize]
- if self.__body:#ugh test if this is necessary
+
+ #ugh test if this is necessary
+ if self.__body:
mp = 0
- def tNone(a, b, c):
- return a == None, b == None, c == None
+
if not self.m_use_geometry:
return latex_linewidths[self.m_papersize][self.m_fontsize]
else:
- if tNone(self.m_geo_lmargin, self.m_geo_width,
- self.m_geo_rmargin) == (1, 1, 1):
+ 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
w = self.get_paperwidth() * 0.8
return w - mp
- elif tNone(self.m_geo_lmargin, self.m_geo_width,
- self.m_geo_rmargin) == (0, 1, 1):
+ elif geo_opts == (0, 1, 1):
if self.m_geo_textwidth:
return self.m_geo_textwidth
return self.f1(self.m_geo_lmargin, mp)
- elif tNone(self.m_geo_lmargin, self.m_geo_width,
- self.m_geo_rmargin) == (1, 1, 0):
+ elif geo_opts == (1, 1, 0):
if self.m_geo_textwidth:
return self.m_geo_textwidth
return self.f1(self.m_geo_rmargin, mp)
- elif tNone(self.m_geo_lmargin, self.m_geo_width,
- self.m_geo_rmargin) \
+ elif geo_opts \
in ((0, 0, 1), (1, 0, 0), (1, 0, 1)):
if self.m_geo_textwidth:
return self.m_geo_textwidth
return self.m_geo_width - mp
- elif tNone(self.m_geo_lmargin, self.m_geo_width,
- self.m_geo_rmargin) in ((0, 1, 0), (0, 0, 0)):
- w = self.get_paperwidth() - self.m_geo_lmargin - self.m_geo_rmargin - mp
+ elif geo_opts in ((0, 1, 0), (0, 0, 0)):
+ w = self.get_paperwidth() \
+ - self.m_geo_lmargin - self.m_geo_rmargin - mp
if w < 0:
w = 0
return w
return x * 2.8452756
def in2pt(x):
return x * 72.26999
-def em2pt(x, fontsize):
+def em2pt(x, fontsize = 10):
return {10: 10.00002, 11: 10.8448, 12: 11.74988}[fontsize] * x
-def ex2pt(x, fontsize):
+def ex2pt(x, fontsize = 10):
return {10: 4.30554, 11: 4.7146, 12: 5.16667}[fontsize] * x
+
+def pt2pt(x):
+ return x
+
+dimension_conversion_dict ={
+ 'mm': mm2pt,
+ 'in': in2pt,
+ 'em': em2pt,
+ 'ex': ex2pt,
+ 'pt': pt2pt
+ }
+
# latex linewidths:
# indices are no. of columns, papersize, fontsize
%s
}
>
-\end{lilypond}""",
- 'output-lilypond':r"""\begin[%s]{lilypond}
+\end{lilypond}""",
+ 'output-filename' : r'''
+
+\verb+%s+:''',
+ 'output-lilypond': r"""\begin[%s]{lilypond}
%s
\end{lilypond}""",
'output-verbatim': "\\begin{verbatim}%s\\end{verbatim}",
%s
@end lilypond
""",
+ 'output-filename' : r'''
+
+@file{%s}:''',
'output-lilypond-fragment': """@lilypond[%s]
\context Staff\context Voice{ %s }
@end lilypond """,
'singleline-comment': r"(?m)^.*?(?P<match>(?P<code>^%.*$\n+))",
'numcols': r"(?P<code>\\(?P<num>one|two)column)",
},
-
+
+
+ # why do we have distinction between @mbinclude and @include?
'texi': {
'include': '(?m)^[^%\n]*?(?P<match>@mbinclude[ \n\t]+(?P<filename>[^\t \n]*))',
'input': no_match,
if 'singleline' in opts:
l = -1.0;
else:
- l = paperguru.get_linewidth()
+ l = __main__.paperguru.get_linewidth()
if 'relative' in opts:#ugh only when is_fragment
body = '\\relative c { %s }' % body
optstring = string.join (opts, ' ')
optstring = re.sub ('\n', ' ', optstring)
body = r"""
-%% Generated by lilypond-book.py; options are %s %%ughUGH not original options
+%% Generated automatically by: lilypond-book.py
+%% options are %s %%ughUGH not original options
\include "paper%d.ly"
\paper { linewidth = %f \pt; }
""" % (optstring, music_size, l) + body
s = s[m.end():]
d[m.group(1)] = 1
continue
- print "trøbbel:%s:" % s
+
+ error ("format of option string invalid (was `%')" % s)
return d
def scan_latex_preamble(chunks):
def scan_texi_preamble (chunks):
# this is not bulletproof..., it checks the first 10 chunks
- idx = 0
- while 1:
- if chunks[idx][0] == 'input':
+ for c in chunks[:10]:
+ if c[0] == 'input':
for s in ('afourpaper', 'afourwide', 'letterpaper',
'afourlatex', 'smallbook'):
- if string.find(chunks[idx][1], "@%s" % s) != -1:
+ if string.find(c[1], "@%s" % s) != -1:
paperguru.m_papersize = s
- idx = idx + 1
- if idx == 10 or idx == len(chunks):
- break
def scan_preamble (chunks):
if __main__.format == 'texi':
read_files = []
def find_file (name):
+ """
+ Search the include path for NAME. If found, return the (CONTENTS, PATH) of the file.
+ """
+
f = None
+ nm = ''
for a in include_path:
try:
nm = os.path.join (a, name)
except IOError:
pass
if f:
- return f.read ()
+ sys.stderr.write ("Reading `%s'\n" % nm)
+ return (f.read (), nm)
else:
error ("File not found `%s'\n" % name)
- return ''
+ return ('', '')
def do_ignore(match_object):
return [('ignore', match_object.group('code'))]
(options, m.group('code')))]
def make_lilypond_file(m):
+ """
+
+ Find @lilypondfile{bla.ly} occurences and substitute bla.ly
+ into a @lilypond .. @end lilypond block.
+
+ """
+
if m.group('options'):
options = m.group('options')
else:
options = ''
+ (content, nm) = find_file(m.group('filename'))
+ options = "filename=%s," % nm + options
+
return [('input', get_output('output-lilypond') %
- (options, find_file(m.group('filename'))))]
+ (options, content))]
def make_lilypond_block(m):
if m.group('options'):
newchunks.append(c)
return newchunks
-def read_doc_file (filename):
- """Read the input file, find verbatim chunks and do \input and \include
- """
- str = ''
- str = find_file(filename)
-
+def determine_format (str):
if __main__.format == '':
+
latex = re.search ('\\\\document', str[:200])
texinfo = re.search ('@node|@setfilename', str[:200])
- if (texinfo and latex) or not (texinfo or latex):
+
+ f = ''
+ g = None
+
+ if texinfo and latex == None:
+ f = 'texi'
+ elif latex and texinfo == None:
+ f = 'latex'
+ else:
error("error: can't determine format, please specify")
- if texinfo:
- __main__.format = 'texi'
+ __main__.format = f
+
+ if __main__.paperguru == None:
+ if __main__.format == 'texi':
+ g = TexiPaper()
else:
- __main__.format = 'latex'
- if __main__.format == 'texi':
- __main__.paperguru = TexiPaper()
- else:
- __main__.paperguru = LatexPaper()
+ g = LatexPaper()
+
+ __main__.paperguru = g
+
+
+def read_doc_file (filename):
+ """Read the input file, find verbatim chunks and do \input and \include
+ """
+ (str, path) = find_file(filename)
+ determine_format (str)
+
chunks = [('input', str)]
+
# we have to check for verbatim before doing include,
# because we don't want to include files that are mentioned
# inside a verbatim environment
(type, body, opts) = chunk
assert type == 'lilypond'
file_body = compose_full_body (body, opts)
- basename = `abs(hash (file_body))`
+ basename = 'lily-' + `abs(hash (file_body))`
for o in opts:
m = re.search ('filename="(.*?)"', o)
if m:
if 'png' in needed_filetypes and f(pathbase, '.eps', '.png'):
todo.append('png')
newbody = ''
+
+ if 'printfilename' in opts:
+ for o in opts:
+ m= re.match ("filename=(.*)", o)
+ if m:
+ newbody = newbody + get_output ("output-filename") % m.group(1)
+ break
+
+
if 'verbatim' in opts:
newbody = output_verbatim (body)
return st
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, ' ' )
+ if do_deps:
+ lilyopts = lilyopts + ' --dependencies '
+ 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 .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' + foutn + ':', text)
+ open (i, 'w').write (text)
+
for e in eps:
system(r"tex '\nonstopmode \input %s'" % e)
system(r"dvips -E -o %s %s" % (e + '.eps', e))
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)
+ os.chdir (d)
def update_file (body, name):
sys.exit (0)
-def write_deps (fn, target):
- sys.stdout.write('writing `%s\'\n' % os.path.join(g_outdir, fn))
+def write_deps (fn, target, chunks):
+ global read_files
+ 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 __main__.read_files:
+ for d in read_files:
f.write ('%s ' % d)
+ basenames=[]
+ for c in chunks:
+ if c[0] == 'lilypond':
+ (type, body, opts, todo, basename) = c;
+ basenames.append (basename)
+ 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):
+ # for d in basenames:
+ # f.write ('%s.ly ' % d)
+ # f.write (' : %s' % target)
f.write ('\n')
f.close ()
- __main__.read_files = []
+ read_files = []
def identify():
sys.stdout.write ('lilypond-book (GNU LilyPond) %s\n' % program_version)
(type, body, opts, todo, basename) = c;
pathbase = os.path.join (g_outdir, basename)
if os.path.isfile (pathbase + '.texidoc'):
- body = '\n@include %s.texidoc' % basename + body
+ body = '\n@include %s.texidoc\n' % basename + body
c = (type, body, opts, todo, basename)
n.append (c)
return n
for c in chunks:
if c[0] == 'lilypond' and 'eps' in c[2]:
body = re.sub (r"""\\lilypondepswidth{(.*?)}""", find_eps_dims, c[1])
- # why do we junk opts, todo, basename?
- new_chunk = (('lilypond', body))
- newchunks.append (c)
+ newchunks.append(('lilypond', body, c[2], c[3], c[4]))
+ else:
+ newchunks.append (c)
return newchunks
+foutn=""
def do_file(input_filename):
+ global foutn
file_settings = {}
if outname:
my_outname = outname
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:
# should chmod -w
if do_deps:
- write_deps (my_depname, foutn)
+ write_deps (my_depname, foutn, chunks)
outname = ''