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.