Parses a variable-sized note number in a tail field. Although
in theory banders are supposed to use only numbers here, again
we are much more permissive: we'll accept any one or two
characters neither of which are TAIL_CUE_CHAR.
The class attribute NOTE_PAT is a compiled
regular expression that matches just that.
# - - - B a s e E n c o u n t e r . t a i l N o t e - - -
NOTE_PAT = re.compile(r"[^%s]{1,2}" % TAIL_CUE_CHAR)
def tailNote(self, scan):
'''Parse a free-field note number.
[ scan is a Scan object ->
if scan starts with a note field ->
scan := scan advanced past that field
self.(DISPOSITION_ATTR) := a NoteField object
representing that field
else ->
Log() +:= error message(s)
raise SyntaxError ]
'''
#-- 1 --
# [ if scan starts with a string that matches self.NOTE_PAT ->
# scan := scan advanced past that string
# s := that string
# else ->
# Log() +:= error message(s)
# raise SyntaxError ]
m = scan.tabReMatch(self.NOTE_PAT)
if m is None:
scan.syntax("Expecting a note number.")
else:
s = m.group()
#-- 2 --
# [ self.(NOTE_ATTR) := a new NoteField object with
# value s ]
setattr(self, NOTE_ATTR, NoteField(self, s))
You might ask, how come we can't use the .scanField() static method of the NoteField class? It's because note fields in the
MAPS 2006 protocol are free-field, while they are fixed-field
in the MAPS 2004 protocol. The NoteField.scanField() method works on a fixed-size
field.