cwd = os.getcwd ()
include_path = [cwd]
-# TODO: use splitting iso. \mudelagraphic.
+# TODO: Figure out clean set of options.
+# BUG: does not handle \verb|\begin{verbatim}\end{verbatim}| correctly.
+# Should make a joint RE for \verb and \begin, \end{verbatim}
#
+
default_music_fontsize = 16
default_text_fontsize = 12
]
format = ''
-no_lily = 0
+run_lilypond = 1
+use_hash = 1
no_match = 'a\ba'
# format specific strings, ie. regex-es for input, and % strings for output
}
>
\end{mudela}""",
- 'output-mudela':r"""\begin%s{mudela}
+ 'output-mudela':r"""\begin[%s]{mudela}
%s
\end{mudela}""",
'output-verbatim': r"""\begin{verbatim}%s\end{verbatim}""",
%s
@end example
""",
+
+# do some tweaking: @ is needed in some ps stuff.
+# override EndLilyPondOutput, since @tex is done
+# in a sandbox, you can't do \input lilyponddefs at the
+# top of the document.
'output-all': r"""@tex
+\catcode`\@=12
+\input lilyponddefs
+\def\EndLilyPondOutput{}
\input %s.tex
+\catcode`\@=0
@end tex
@html
<img src=%s.png>
}
}
+def output_verbatim (body):
+ if __main__.format == 'texi':
+ body = re.sub ('([@{}])', '@\\1', body)
+ return get_output ('output-verbatim') % body
+
re_dict = {
'latex': {'input': '\\\\input{?([^}\t \n}]*)',
'include': '\\\\include{([^}]+)}',
'mudela-file': '@mudelafile(\[[^\\]]+\])?{([^}]+)}',
'mudela' : '@mudela(\[.*?\])?{(.*?)}',
'mudela-block': r"""(?s)@mudela(\[.*?\])?(.*?)@end mudela""",
- 'interesting-cs': r"""[\\@](node|mudelagraphic)""",
+ 'interesting-cs': r"""[\\@](chapter|section)""",
'comma-sep' : ', *',
}
}
re_dict[r] = newdict
+def uniq (list):
+ list.sort ()
+ s = list
+ list = []
+ for x in s:
+ if x not in list:
+ list.append (x)
+ return list
+
+
def get_output (name):
return output_dict[format][name]
if 'twocolumn' in opts:
cols = 2
- if 'fragment' or 'singleline' in opts:
+
+ # urg: breaks on \include of full score
+ # Use nofly option if you want to \include full score.
+ if 'nofly' not in opts and not re.search ('\\\\score', body):
+ opts.append ('fragment')
+
+ if 'fragment' in opts and 'nosingleline' not in opts:
+ opts.append ('singleline')
+
+ if 'singleline' in opts:
l = -1.0;
else:
l = latex_linewidths[cols][paper][latex_size]
- # urg: breaks on \include of full score
- # if not 'nofly' in opts and not re.search ('\\\\score', body):
- # opts.append ('fly')
- if 'fly' in opts:
+ if 'relative' in opts:
+ body = '\\relative c { %s }' % body
+
+
+ if 'fragment' in opts:
body = r"""\score {
- \notes\relative c {
- %s
- }
+ \notes { %s }
\paper { }
}""" % body
-
+ opts = uniq (opts)
+ optstring = string.join (opts, ' ')
+ optstring = re.sub ('\n', ' ', optstring)
+
body = r"""
-%% Generated by mudela-book.py
+%% Generated by mudela-book.py; options are %s
\include "paper%d.ly"
\paper { linewidth = %f \pt; }
-""" % (music_size, l) + body
+""" % (optstring, music_size, l) + body
return body
-def inclusion_func (match, surround):
- insert = match.group (0)
- try:
- (insert, d) = read_doc_file (match.group(1))
- deps = deps + d
- insert = surround + insert + surround
- except:
- sys.stderr.write("warning: can't find %s, let's hope latex will\n" % m.group(1))
-
- return (insert, deps)
-
def find_inclusion_chunks (regex, surround, str):
chunks = []
while str:
def read_doc_file (filename):
"""Read the input file, substituting for \input, \include, \mudela{} and \mudelafile"""
str = ''
- for fn in [filename, filename+'.tex', filename+'.doc']:
+ for ext in ['', '.tex', '.doc', '.tely']:
try:
- f = open(fn)
+ f = open(filename+ ext)
str = f.read (-1)
except:
pass
if not str:
- raise IOError
+ error ("File not found `%s'\n" % filename)
retdeps = [filename]
else:
__main__.format = 'latex'
- chunks = find_verbatim_chunks (str)
- newchunks = []
+ chunks = [('input', str)]
- for func in (find_include_chunks, find_input_chunks):
+ for func in (find_verbatim_chunks, find_verb_chunks, find_include_chunks, find_input_chunks):
+ newchunks = []
for c in chunks:
if c[0] == 'input':
ch = func (c[1])
newchunks = newchunks + ch
else:
newchunks.append (c)
-
+ chunks = newchunks
return chunks
(TYPE_STR, CONTENT_STR), where TYPE_STR is one of 'input' and 'verbatim'
"""
-
chunks = []
-
while str:
m = get_re ('verbatim').search( str)
- m2 = get_re ("verb").search( str)
+ if m == None:
+ chunks.append( ('input', str))
+ str = ''
+ else:
+ chunks.append (('input', str[:m.start (0)]))
+ chunks.append (('verbatim', m.group (0)))
+
+ str = str [m.end(0):]
+
+ return chunks
+
+def find_verb_chunks (str):
- if m == None and m2 == None:
+ chunks = []
+ while str:
+ m = get_re ("verb").search(str)
+ if m == None:
chunks.append (('input', str))
str = ''
- break
-
- if m == None:
- m = m2
+ else:
+ chunks.append (('input', str[:m.start (0)]))
+ chunks.append (('verbatim', m.group (0)))
+ str = str [m.end(0):]
- if m2 and m2.start (0) < m.start (0):
- m = m2
+ return chunks
- chunks.append (('input', str[:m.start (0)]))
- chunks.append (('verbatim', m.group (0)))
-
- str = str [m.end(0):]
- return chunks
def find_mudela_shorthand_chunks (str):
str = f.read (-1)
opts = match.group (1)
if opts:
- opts = re.split (',[ \n\t]*', opts[1:-1])
+ opts = opts[1:-1]
+ opts = re.split (',[ \n\t]*', opts)
else:
opts = []
opts .append ('nofly')
str_opts = string.join (opts, ',')
- if str_opts: str_opts = '[' + str_opts + ']'
-
- str = "%% copied from %s" % full_path + str
+ str = ("%% copied from file `%s'\n" % full_path) + str
return get_output ('output-mudela') % (str_opts, str)
-
+
b = get_re('mudela-file').sub (mudela_file, b)
b = get_re('mudela').sub (mudela_short, b)
return b
def find_mudela_chunks (str):
"""Find mudela blocks, while watching for verbatim. Returns
- (STR,MUDS) with \mudelagraphic substituted for the blocks in STR,
+ (STR,MUDS) with substituted for the blocks in STR,
and the blocks themselves MUDS"""
-
+
chunks = []
while str:
m = get_re ("mudela-block").search( str)
chunks.append (('input', str[:m.start (0)]))
opts = m.group (1)
- if opts:
- opts = opts[1:-1]
- else:
- opts = ''
+ if opts:
+ opts = opts[1:-1]
+ else:
+ opts = ''
optlist = get_re('comma-sep').split (opts)
body = m.group (2)
chunks.append (('mudela', body, optlist))
-
+
str = str [m.end (0):]
-
+
return chunks
-
-
-
+
+
+
def advance_counters (counter, opts, str):
"""Advance chap/sect counters,
revise OPTS. Return the new counter tuple"""
(chapter, section, count) = counter
- done = ''
- while str:
+ done = ''
+ while str:
m = get_re ('interesting-cs').search(str)
if not m:
done = done + str
pass
elif g == 'chapter':
(chapter, section, count) = (chapter + 1, 0, 0)
- elif g == 'section' or g == 'node':
+ elif g == 'section':
(section, count) = (section + 1, 0)
def schedule_mudela_block (base, chunk, extra_opts):
-
"""Take the body and options from CHUNK, figure out how the
real .ly should look, and what should be left MAIN_STR (meant
for the main file). The .ly is written, and scheduled in
TODO.
- Return: a chunk (TYPE_STR, MAIN_STR, OPTIONS, TODO)
+ Return: a chunk (TYPE_STR, MAIN_STR, OPTIONS, TODO, BASE)
TODO has format [basename, extension, extension, ... ]
newbody = ''
if 'verbatim' in opts:
- verbatim_mangle = body
- if __main__.format == 'texi':
- verbatim_mangle = re.sub ('([{}])', '@\\1', body)
- newbody = get_output ('output-verbatim') % verbatim_mangle
+ newbody = output_verbatim (body)
file_body = compose_full_body (body, opts)
- updated = update_file (file_body, base + '.ly')
+ basename = base
+ if __main__.use_hash:
+ basename = `hash (file_body)`
+ updated = update_file (file_body, basename + '.ly')
+ todo = [basename] # UGH.
- todo = [base] # UGH.
-
- if not os.path.isfile (base + '.tex') or updated:
+ if not os.path.isfile (basename + '.tex') or updated:
todo.append ('tex')
updated = 1
opts.append ('eps')
if 'eps' in opts and ('tex' in todo or
- not os.path.isfile (base + '.eps')):
+ not os.path.isfile (basename + '.eps')):
todo.append ('eps')
if 'png' in opts and ('eps' in todo or
- not os.path.isfile (base + '.png')):
+ not os.path.isfile (basename + '.png')):
todo.append ('png')
if format == 'latex':
if 'eps' in opts :
- newbody = newbody + get_output ('output-eps') % (base, base)
+ newbody = newbody + get_output ('output-eps') % (basename, basename)
else:
- newbody = newbody + get_output ('output-tex') % base
+ newbody = newbody + get_output ('output-tex') % basename
elif format == 'texi':
- newbody = newbody + get_output ('output-all') % (base, base)
+ newbody = newbody + get_output ('output-all') % (basename, basename)
+ return ('mudela', newbody, opts, todo, base)
-
- return ('mudela', newbody, opts, todo)
def find_eps_dims (match):
"Fill in dimensions of EPS files."
+
fn =match.group (1)
dims = bounding_box_dimensions (fn)
chunks = newchunks
newchunks = []
-
# Do It.
- if not __main__.no_lily:
+ if __main__.run_lilypond:
compile_all_files (chunks)
# finishing touch.
for c in chunks:
- if c[0] == 'mudela' and 'eps' in c[2]:
+ if c[0] == 'mudela' and 'eps' in c[2]:
body = re.sub (r"""\\mudelaepswidth{(.*?)}""", find_eps_dims, c[1])
newchunks.append (('mudela', body))
else:
newchunks.append (c)
-
- if chunks and chunks[0][0] == 'input':
- chunks[0] = ('input', completize_preamble (chunks[0][1]))
+ chunks = newchunks
+ if chunks and chunks[0][0] == 'input':
+ chunks[0] = ('input', completize_preamble (chunks[0][1]))
+
return chunks
def system (cmd):
sys.stderr.write ("invoking `%s'\n" % cmd)
st = os.system (cmd)
if st:
- sys.stderr.write ('Error command exited with value %d\n' % st)
+ error ('Error command exited with value %d\n' % st)
return st
def compile_all_files (chunks):
eps = []
tex = []
png = []
+ hash_dict = {}
for c in chunks:
if c[0] <> 'mudela':
elif e == 'png':
png.append (base)
+ if __main__.use_hash:
+ hash_dict[c[4]] = c[3][0]
+
if tex:
lilyopts = map (lambda x: '-I ' + x, include_path)
lilyopts = string.join (lilyopts, ' ' )
cmd = cmd % (g + '.eps', g + '.png')
system (cmd)
+ if __main__.use_hash:
+ name = ''
+ last_name = ''
+ f = 0
+ ks = hash_dict.keys ()
+ ks.sort ()
+ for i in ks:
+ name = re.sub ("(.*)-[0-9]+\.[0-9]+\.[0-9]+", "\\1", i)
+ name = name + '.mix'
+ if name != last_name:
+ if last_name:
+ f.close ()
+ f = open (name, 'w')
+ last_name = name
+ f.write ("%s:%s\n" % (i, hash_dict[i]))
+
def update_file (body, name):
same = 0
elif o == '--help' or o == '-h':
help ()
elif o == '--no-lily' or o == '-n':
- __main__.no_lily = 1
+ __main__.run_lilypond = 0
elif o == '--dependencies':
do_deps = 1
elif o == '--default-mudela-fontsize':