]> git.donarmstrong.com Git - lilypond.git/blobdiff - scripts/abc2ly.py
Docs-hu: Fix missing menu from Learning 1.3 Docs-hu: Polish navigation translation...
[lilypond.git] / scripts / abc2ly.py
index be84071e9f817c0d679afb15c95ff716827b5964..02ff95ba9341aae986daef18528595cf0b36b382 100644 (file)
@@ -1,6 +1,23 @@
 #!@TARGET_PYTHON@
 # -*- coding: utf-8 -*-
+
 # once upon a rainy monday afternoon.
+
+#    This file is part of LilyPond, the GNU music typesetter.
+#
+#    LilyPond is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    LilyPond is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+
 #
 #   ...
 #
@@ -123,32 +140,45 @@ def alphabet (i):
     return chr (i + ord('A'))
     
 def check_clef(s):
+    # the number gives the base_octave
+    clefs = [("treble", "treble", 0),
+             ("treble1", "french", 0),
+             ("bass3", "varbaritone", 0),
+             ("bass", "bass", 0),
+             ("alto4", "tenor", 0),
+             ("alto2", "mezzosoprano", 0),
+             ("alto1", "soprano", 0),
+             ("alto", "alto", 0),
+             ("perc", "percussion", 0)]
+    modifier = [("-8va", "_8", -1),
+                ("-8", "_8", -1),
+                ("\+8", "^8", +1),
+                ("8", "_8", -1)]
+
     if not s:
         return ''
-    if re.match('-8va', s) or re.match('treble8', s):
-        # treble8 is used by abctab2ps; -8va is used by barfly,
-        # and by my patch to abc2ps. If there's ever a standard
-        # about this we'll support that.
-        s = s[4:]
-        state.base_octave = -1
-        voices_append("\\clef \"G_8\"\n")
-    elif re.match('^treble', s):
-        s = s[6:]
-        if re.match ('^-8', s):
-            s = s[2:]
-            state.base_octave = -2
-            voices_append("\\clef \"G_8\"\n")
-        else:
-            state.base_octave = 0
-            voices_append("\\clef treble\n")
-    elif re.match('^alto', s):
-        s = s[4:]
-        state.base_octave = -1
-        voices_append ("\\clef alto\n" )
-    elif re.match('^bass',s ):
-        s = s[4:]
-        state.base_octave = -2
-        voices_append ("\\clef bass\n" )
+    clef = None;
+    octave = 0;
+    for c in clefs:
+      m = re.match('^'+c[0], s)
+      if m:
+        (clef, octave) = (c[1], c[2])
+        s = s[m.end():]
+        break;
+    if not clef:
+      return s
+
+    mod = "";
+    for md in modifier:
+      m = re.match('^'+md[0], s)
+      if m:
+        mod = md[1];
+        octave += md[2];
+        s = s[m.end():]
+        break;
+
+    state.base_octave = octave
+    voices_append ("\\clef \""+clef+mod+"\"\n")
     return s
 
 def select_voice (name, rol):
@@ -216,7 +246,7 @@ def dump_slyrics (outf):
             m = k
         for i in range (len(slyrics[voice_idx_dict[k]])):
             l= alphabet(i)
-            outf.write ("\nwords%sV%s = \lyricmode {" % (m, l))
+            outf.write ("\nwords%sV%s = \\lyricmode {" % (m, l))
             outf.write ("\n" + slyrics [voice_idx_dict[k]][i])
             outf.write ("\n}")
 
@@ -242,19 +272,17 @@ def dump_voices (outf):
         outf.write ("\n}")
 
 def try_parse_q(a):
-    global midi_specs
-    #assume that Q takes the form "Q:1/4=120"
+    #assume that Q takes the form "Q:'opt. description' 1/4=120"
     #There are other possibilities, but they are deprecated
-    if a.count ('/') == 1:
-        array = a.split('/')
-        numerator=array[0]
-        if int(numerator) != 1:
-            sys.stderr.write("abc2ly: Warning, unable to translate a Q specification with a numerator of %s: %s\n" % (numerator, a))
-        array2 = array[1].split ('=')
-        denominator=array2[0]
-        perminute=array2[1]
-        duration = str (int (denominator) / int (numerator))
-        midi_specs = ' '.join(["    \n\t\t\context {\n\t\t \Score tempoWholesPerMinute = #(ly:make-moment ", perminute, " ", duration, ")\n\t\t }\n"])
+    r = re.compile ('^(.*) *([0-9]+) */ *([0-9]+) *=* *([0-9]+)\s*')
+    m = r.match (a)
+    if m:
+        descr = m.group(1) # possibly empty
+        numerator = int(m.group (2))
+        denominator = int(m.group (3))
+        tempo = m.group (4)
+        dur = duration_to_lilypond_duration ((numerator,denominator), 1, 0)
+        voices_append ("\\tempo " + descr + " " + dur + "=" + tempo + "\n")
     else:
         sys.stderr.write("abc2ly: Warning, unable to parse Q specification: %s\n" % a)
 
@@ -282,7 +310,7 @@ def dump_score (outf):
 
         l = ord( 'A' )
         for lyrics in slyrics [voice_idx_dict[k]]:
-            outf.write ("\n\t\\addlyrics { \n")
+            outf.write ("\n\t\\addlyrics {\n")
             if re.match('[1-9]',k):
                 m = alphabet (int (k))
             else:
@@ -650,12 +678,12 @@ def try_parse_header_line (ln, state):
             if a == 'C':
                 if not state.common_time:
                     state.common_time = 1
-                    voices_append (" \\override Staff.TimeSignature #\'style = #'C\n")
+                    voices_append (" \\override Staff.TimeSignature #'style = #'C\n")
                 a = '4/4'
             if a == 'C|':
                 if not state.common_time:
                     state.common_time = 1
-                    voices_append ("\\override Staff.TimeSignature #\'style = #'C\n")
+                    voices_append ("\\override Staff.TimeSignature #'style = #'C\n")
                 a = '2/2'
             if not length_specified:
                 set_default_len_from_time_sig (a)
@@ -667,16 +695,19 @@ def try_parse_header_line (ln, state):
         if g == 'K': # KEY
             a = check_clef(a)
             if a:
-                m = re.match ('^([^ \t]*) *(.*)$', a) # seperate clef info
+                m = re.match ('^([^ \t]*) *([^ ]*)( *)(.*)$', a) # seperate clef info
                 if m:
                     # there may or may not be a space
                     # between the key letter and the mode
-                    if key_lookup.has_key(m.group(2)[0:3]):
-                        key_info = m.group(1) + m.group(2)[0:3]
-                        clef_info = m.group(2)[4:]
+                    # convert the mode to lower-case before comparing
+                    mode = m.group(2)[0:3].lower();
+                    if key_lookup.has_key(mode):
+                        # use the full mode, not only the first three letters
+                        key_info = m.group(1) + m.group(2).lower()
+                        clef_info = a[m.start(4):]
                     else:
                         key_info = m.group(1)
-                        clef_info = m.group(2)
+                        clef_info = a[m.start(2):]
                     __main__.global_key  = compute_key (key_info)
                     k = lily_key (key_info)
                     if k:
@@ -779,7 +810,7 @@ def duration_to_lilypond_duration  (multiply_tup, defaultlen, dots):
             base = '\\breve'
             dots = 1
         if (multiply_tup[0] / multiply_tup[1]) == 4:
-            base = '\longa'
+            base = '\\longa'
     return '%s%s' % ( base, '.'* dots)
 
 class Parser_state:
@@ -928,8 +959,7 @@ def get_bar_acc(note, octave, state):
         return(UNDEF)
 
 def clear_bar_acc(state):
-    for k in state.in_acc:
-        del state.in_acc[k]
+    state.in_acc = {}
 
 
 # if we are parsing a beam, close it off
@@ -1358,11 +1388,12 @@ def get_option_parser ():
                   action='store')
     p.add_option ('-s', '--strict', help=_ ("be strict about success"),
                   action='store_true')
-    p.add_option ('-b', '--beams', help=_ ("preserve ABC's notion of beams"))
+    p.add_option ('-b', '--beams', help=_ ("preserve ABC's notion of beams"), action="store_true")
     p.add_option_group ('',
-                        description=(_ ('Report bugs via')
-                                     + ''' http://post.gmane.org/post.php'''
-                                     '''?group=gmane.comp.gnu.lilypond.bugs\n'''))
+                        description=(
+            _ ('Report bugs via %s')
+            % 'http://post.gmane.org/post.php'
+            '?group=gmane.comp.gnu.lilypond.bugs') + '\n')
     return p