#!@PYTHON@
+'''
+Exampel usage:
+
+test:
+ filter-lilypond-book --filter="tr '[a-z]' '[A-Z]'" BOOK
+
+convert-ly on book:
+ filter-lilypond-book --filter="convert-ly --no-version --from=1.6.11 -" BOOK
+
+minimal classic lilypond-book (WIP):
+ filter-lilypond-book --process="lilypond-bin" BOOK.tely
+
+ (([0-9][0-9])*pt) -> staffsize=\2
+
+'''
+
import string
+import __main__
################################################################
# Users of python modules should include this snippet
filter-lilypond-book --filter="convert-ly --no-version --from=1.6.11 -" BOOK
""")
-copyright = ('Tom Cato Amundsen <tca@gnu.org>',
+copyright = ('Jan Nieuwenhuizen <janneke@gnu.org>>',
'Han-Wen Nienhuys <hanwen@cs.uu.nl>')
option_definitions = [
lilypond_binary = 'lilypond-bin'
+use_hash_p = 1
format = 0
filter_cmd = 'convert-ly --no-version --from=2.0.0 -'
#filter_cmd = 0
#process_cmd = 'convert-ly --no-version --from=2.0.0'
process_cmd = 0
+LATEX = 'latex'
+HTML = 'html'
+TEXINFO = 'texinfo'
+BEFORE = 'before'
+AFTER = 'after'
+
+## lilypond-book heritage. to be cleaned
+
################################################################
# Recognize special sequences in the input
# (?s) -- make the dot match all characters including newline
no_match = 'a\ba'
re_dict = {
- 'html': {
+ HTML: {
'include': no_match,
'input': no_match,
'header': no_match,
'ly2dvi': r'(?m)(?P<match><ly2dvifile(?P<options>[^>]+)?>\s*(?P<filename>[^<]+)\s*</ly2dvifile>)',
},
- 'latex': {
+ LATEX: {
'input': r'(?m)^[^%\n]*?(?P<match>\\mbinput{?([^}\t \n}]*))',
'include': r'(?m)^[^%\n]*?(?P<match>\\mbinclude{(?P<filename>[^}]+)})',
'option-sep' : ',\s*',
# why do we have distinction between @mbinclude and @include?
- 'texinfo': {
+ TEXINFO: {
'include': '(?m)^[^%\n]*?(?P<match>@mbinclude\s+(?P<filename>\S*))',
'input': no_match,
'header': no_match,
}
}
-def compose_ly (code, options):
+NOTES = 'body'
+PREAMBLE = 'preamble'
+PAPER = 'paper'
+
+ly_options = {
+ NOTES: {
+ 'relative': r'''\relative #(ly:make-pitch %(relative)s 0 0)'''
+ },
+ PAPER: {
+ 'indent' : r'''
+ indent = %(indent)s''',
+ 'linewidth' : r'''
+ linewidth = %(linewidth)s''',
+ 'noindent' : r'''
+ indent = 0.0\mm''',
+ 'notime' : r'''
+ \translator {
+ \StaffContext
+ \remove Time_signature_engraver
+ }''',
+ 'raggedright' : r'''
+ raggedright = ##t''',
+ },
+ PREAMBLE: {
+ 'staffsize': r'''
+#(set-global-staff-size %(staffsize)s)''',
+ },
+ }
+
+
+PREAMBLE_LY = r'''%% Generated by %(program_name)s
+%% Options: [%(option_string)s]
+%(preamble_string)s
+\paper {%(paper_string)s
+}
+'''
+
+FRAGMENT_LY = r'''\score{
+ \notes%(notes_string)s{
+ %(code)s }
+}'''
+FULL_LY = '%(code)s'
+
+
+def compose_ly (code, option_string):
m = re.search (r'''\\score''', code)
+ options = string.split (option_string, ',')
if not m and (not options \
or not 'nofragment' in options \
or 'fragment' in options):
- body = r'''\score{\notes{ %(code)s }}''' % vars ()
+ body = FRAGMENT_LY
else:
- body = code
- ### todo: add options
- return body
-
-
-LATEX = 'latex'
-HTML = 'html'
-TEXINFO = 'texinfo'
-BEFORE = 'before'
-AFTER = 'after'
+ body = FULL_LY
+
+ # defaults
+ relative = "0"
+ staffsize = "16"
+
+ notes_options = []
+ paper_options = []
+ preamble_options = []
+ for i in options:
+ if string.find (i, '=') > 0:
+ key, value = string.split (i, '=')
+ # hmm
+ vars ()[key] = value
+ else:
+ key = i
+
+ if key in ly_options[NOTES].keys ():
+ notes_options.append (ly_options[NOTES][key] % vars ())
+ elif key in ly_options[PREAMBLE].keys ():
+ preamble_options.append (ly_options[PREAMBLE][key] \
+ % vars ())
+ elif key in ly_options[PAPER].keys ():
+ paper_options.append (ly_options[PAPER][key] % vars ())
+
+ program_name = __main__.program_name
+ notes_string = string.join (notes_options, '\n ')
+ paper_string = string.join (paper_options, '\n ')
+ preamble_string = string.join (preamble_options, '\n ')
+ return (PREAMBLE_LY + body) % vars ()
output = {
HTML : {
return self.hash
def basename (self, source):
- return 'lily-%d' % self.get_hash (source)
+ if use_hash_p:
+ return 'lily-%d' % self.get_hash (source)
+ raise 'to be done'
def write_ly (self, source):
h = open (self.basename (source) + '.ly', 'w')
base = self.basename (source)
if os.path.exists (base + '.ly') \
and os.path.exists (base + '.tex') \
- and self.ly (source) == open (base + '.ly').read ():
+ and (not use_hash_p \
+ or self.ly (source) == open (base + '.ly').read ()):
# TODO: something smart with target formats
- # (ps, png) and m/atimes
+ # (ps, png) and m/ctimes
return None
return self