Skip to content

Commit f99e433

Browse files
authored
Merge branch 'master' into midi-recording-mac
2 parents 645836c + 1165e10 commit f99e433

16 files changed

+900
-509
lines changed

abc2xml.py

+45-28
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
'''
44
Copyright (C) 2012-2018: Willem G. Vree
55
Contributions: Nils Liberg, Nicolas Froment, Norman Schmidt, Reinier Maliepaard, Martin Tarenskeen,
6-
Paul Villiger, Alexander Scheutzow, Herbert Schneider, David Randolph
6+
Paul Villiger, Alexander Scheutzow, Herbert Schneider, David Randolph, Michael Strasser
77
88
This program is free software; you can redistribute it and/or modify it under the terms of the
99
Lesser GNU General Public License as published by the Free Software Foundation;
@@ -22,7 +22,7 @@
2222
except: import xml.etree.ElementTree as E
2323
import types, sys, os, re, datetime
2424

25-
VERSION = 228
25+
VERSION = 231
2626

2727
python3 = sys.version_info[0] > 2
2828
lmap = lambda f, xs: list (map (f, xs)) # eager map for python 3
@@ -152,13 +152,14 @@ def abc_grammar (): # header, voice and lyrics grammar for ABC
152152
text_expression = Optional (oneOf ('^ _ < > @'), '^') + Optional (CharsNotIn ('"'), "")
153153
chord_accidental = oneOf ('# b =')
154154
triad = oneOf ('ma Maj maj M mi min m aug dim o + -')
155-
seventh = oneOf ('7 ma7 Maj7 M7 maj7 mi7 m7 dim7 o7 -7 aug7 +7 m7b5 mi7b5')
156-
sixth = oneOf ('6 ma6 M6 m6 mi6')
157-
ninth = oneOf ('9 ma9 M9 maj9 Maj9 mi9 m9')
158-
elevn = oneOf ('11 ma11 M11 maj11 Maj11 mi11 m11')
155+
seventh = oneOf ('7 ma7 Maj7 M7 maj7 mi7 min7 m7 dim7 o7 -7 aug7 +7 m7b5 mi7b5')
156+
sixth = oneOf ('6 ma6 M6 mi6 min6 m6')
157+
ninth = oneOf ('9 ma9 M9 maj9 Maj9 mi9 min9 m9')
158+
elevn = oneOf ('11 ma11 M11 maj11 Maj11 mi11 min11 m11')
159+
thirt = oneOf ('13 ma13 M13 maj13 Maj13 mi13 min13 m13')
159160
suspended = oneOf ('sus sus2 sus4')
160161
chord_degree = Combine (Optional (chord_accidental) + oneOf ('2 4 5 6 7 9 11 13'))
161-
chord_kind = Optional (seventh | sixth | ninth | elevn | triad, '_') + Optional (suspended)
162+
chord_kind = Optional (seventh | sixth | ninth | elevn | thirt | triad) + Optional (suspended)
162163
chord_root = oneOf ('C D E F G A B') + Optional (chord_accidental)
163164
chord_bass = oneOf ('C D E F G A B') + Optional (chord_accidental) # needs a different parse action
164165
chordsym = chord_root + chord_kind + ZeroOrMore (chord_degree) + Optional (Suppress ('/') + chord_bass)
@@ -413,14 +414,16 @@ def doGrace (t): # t is a Group() result -> the grace sequence is in t[0]
413414
#----------------------------------
414415

415416
def compChordTab (): # avoid some typing work: returns mapping constant {ABC chordsyms -> musicXML kind}
416-
maj, min, aug, dim, dom, ch7, ch6, ch9, ch11, hd = 'major minor augmented diminished dominant -seventh -sixth -ninth -11th half-diminished'.split ()
417+
maj, min, aug, dim, dom, ch7, ch6, ch9, ch11, ch13, hd = 'major minor augmented diminished dominant -seventh -sixth -ninth -11th -13th half-diminished'.split ()
417418
triad = zip ('ma Maj maj M mi min m aug dim o + -'.split (), [maj, maj, maj, maj, min, min, min, aug, dim, dim, aug, min])
418-
seventh = zip ('7 ma7 Maj7 M7 maj7 mi7 m7 dim7 o7 -7 aug7 +7 m7b5 mi7b5'.split (),
419-
[dom, maj+ch7, maj+ch7, maj+ch7, maj+ch7, min+ch7, min+ch7, dim+ch7, dim+ch7, min+ch7, aug+ch7, aug+ch7, hd, hd])
420-
sixth = zip ('6 ma6 M6 mi6 m6'.split (), [maj+ch6, maj+ch6, maj+ch6, min+ch6, min+ch6])
421-
ninth = zip ('9 ma9 M9 maj9 Maj9 mi9 m9'.split (), [dom+ch9, maj+ch9, maj+ch9, maj+ch9, maj+ch9, min+ch9, min+ch9])
422-
elevn = zip ('11 ma11 M11 maj11 Maj11 mi11 m11'.split (), [dom+ch11, maj+ch11, maj+ch11, maj+ch11, maj+ch11, min+ch11, min+ch11])
423-
return dict (list (triad) + list (seventh) + list (sixth) + list (ninth) + list (elevn))
419+
seventh = zip ('7 ma7 Maj7 M7 maj7 mi7 min7 m7 dim7 o7 -7 aug7 +7 m7b5 mi7b5'.split (),
420+
[dom, maj+ch7, maj+ch7, maj+ch7, maj+ch7, min+ch7, min+ch7, min+ch7, dim+ch7, dim+ch7, min+ch7, aug+ch7, aug+ch7, hd, hd])
421+
sixth = zip ('6 ma6 M6 mi6 min6 m6'.split (), [maj+ch6, maj+ch6, maj+ch6, min+ch6, min+ch6, min+ch6])
422+
ninth = zip ('9 ma9 M9 maj9 Maj9 mi9 min9 m9'.split (), [dom+ch9, maj+ch9, maj+ch9, maj+ch9, maj+ch9, min+ch9, min+ch9, min+ch9])
423+
elevn = zip ('11 ma11 M11 maj11 Maj11 mi11 min11 m11'.split (), [dom+ch11, maj+ch11, maj+ch11, maj+ch11, maj+ch11, min+ch11, min+ch11, min+ch11])
424+
thirt = zip ('13 ma13 M13 maj13 Maj13 mi13 min13 m13'.split (), [dom+ch13, maj+ch13, maj+ch13, maj+ch13, maj+ch13, min+ch13, min+ch13, min+ch13])
425+
sus = zip ('sus sus4 sus2'.split (), ['suspended-fourth', 'suspended-fourth', 'suspended-second'])
426+
return dict (list (triad) + list (seventh) + list (sixth) + list (ninth) + list (elevn) + list (thirt) + list (sus))
424427

425428
def addElem (parent, child, level):
426429
indent = 2
@@ -844,6 +847,7 @@ def reset (s, fOpt=False):
844847
s.lyrdash = {} # {lyric number -> 1 if dash between syllables}
845848
s.usrSyms = s.uSyms # user defined symbols
846849
s.prevNote = None # xml element of previous beamed note to correct beams (start, continue)
850+
s.prevLyric = {} # xml element of previous lyric to add/correct extend type (start, continue)
847851
s.grcbbrk = False # remember any bbrk in a grace sequence
848852
s.linebrk = 0 # 1 if next measure should start with a line break
849853
s.nextdecos = [] # decorations for the next note
@@ -1035,6 +1039,7 @@ def mkNote (s, n, lev):
10351039
if hasStem: s.doBeams (n, nt, den, lev + 1) # no stems -> no beams in a tab staff
10361040
s.doNotations (n, decos, ptup, alter, tupnotation, tstop, nt, lev + 1)
10371041
if n.objs: s.doLyr (n, nt, lev + 1)
1042+
else: s.prevLyric = {} # clear on note without lyrics
10381043
return nt
10391044

10401045
def cmpNormType (s, rdvs, lev): # compute the normal-type of a tuplet (only needed for Finale)
@@ -1198,21 +1203,33 @@ def doArticulations (s, nt, nots, arts, lev):
11981203

11991204
def doLyr (s, n, nt, lev):
12001205
for i, lyrobj in enumerate (n.objs):
1201-
if lyrobj.name != 'syl': continue
1202-
dash = len (lyrobj.t) == 2
1203-
if dash:
1204-
if i in s.lyrdash: type = 'middle'
1205-
else: type = 'begin'; s.lyrdash [i] = 1
1206-
else:
1207-
if i in s.lyrdash: type = 'end'; del s.lyrdash [i]
1208-
else: type = 'single'
12091206
lyrel = E.Element ('lyric', number = str (i + 1))
1207+
if lyrobj.name == 'syl':
1208+
dash = len (lyrobj.t) == 2
1209+
if dash:
1210+
if i in s.lyrdash: type = 'middle'
1211+
else: type = 'begin'; s.lyrdash [i] = 1
1212+
else:
1213+
if i in s.lyrdash: type = 'end'; del s.lyrdash [i]
1214+
else: type = 'single'
1215+
addElemT (lyrel, 'syllabic', type, lev + 1)
1216+
txt = lyrobj.t[0] # the syllabe
1217+
txt = re.sub (r'(?<!\\)~', ' ', txt) # replace ~ by space when not escaped (preceded by \)
1218+
txt = re.sub (r'\\(.)', r'\1', txt) # replace all escaped characters by themselves (for the time being)
1219+
addElemT (lyrel, 'text', txt, lev + 1)
1220+
elif lyrobj.name == 'ext' and i in s.prevLyric:
1221+
pext = s.prevLyric [i].find ('extend') # identify previous extend
1222+
if pext == None:
1223+
ext = E.Element ('extend', type = 'start')
1224+
addElem (s.prevLyric [i], ext, lev + 1)
1225+
elif pext.get('type') == 'stop': # subsequent extend: stop -> continue
1226+
pext.set ('type', 'continue')
1227+
ext = E.Element ('extend', type = 'stop') # always stop on current extend
1228+
addElem (lyrel, ext, lev + 1)
1229+
elif lyrobj.name == 'ext': info ('lyric extend error'); continue
1230+
else: continue # skip other lyric elements or errors
12101231
addElem (nt, lyrel, lev)
1211-
addElemT (lyrel, 'syllabic', type, lev + 1)
1212-
txt = lyrobj.t[0] # the syllabe
1213-
txt = re.sub (r'(?<!\\)~', ' ', txt) # replace ~ by space when not escaped (preceded by \)
1214-
txt = re.sub (r'\\(.)', r'\1', txt) # replace all escaped characters by themselves (for the time being)
1215-
addElemT (lyrel, 'text', txt, lev + 1)
1232+
s.prevLyric [i] = lyrel # for extension (melisma) on the next note
12161233

12171234
def doBeams (s, n, nt, den, lev):
12181235
if hasattr (n, 'chord') or hasattr (n, 'grace'):
@@ -1535,7 +1552,7 @@ def doChordSym (s, maat, sym, lev):
15351552
addElem (chord, root, lev + 1)
15361553
addElemT (root, 'root-step', rnt[0], lev + 2)
15371554
if len (rnt) == 2: addElemT (root, 'root-alter', alterMap [rnt[1]], lev + 2)
1538-
kind = s.chordTab.get (sym.kind.t[0], 'major')
1555+
kind = s.chordTab.get (sym.kind.t[0], 'major') if sym.kind.t else 'major'
15391556
addElemT (chord, 'kind', kind, lev + 1)
15401557
if hasattr (sym, 'bass'):
15411558
bnt = sym.bass.t

abc_assist_panel.py

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ def update_assist(self):
138138
self.context.current_element = element
139139
if element is not None:
140140
self.context.set_current_match(match, element.tune_scope)
141+
element = element.get_inner_element(self.context)
141142

142143
html = self.html_header
143144
if element is not None:

0 commit comments

Comments
 (0)