For the format of this field, see the specification.
Unlike other classes derived from FieldItem, this
class parses a variable-length field for the color-band
sequence, since this field appears only in the free-form,
variable-length tail section.
# - - - - - c l a s s C o l o r B a n d s F i e l d - - - - -
class ColorBandsField(FieldItem):
"""Represents a color-band sequence.
Exports: as inherited.
"""
This method parses a color-band string. Although a color-band
string must technically contain exactly one slash (/), one letter S, and at least one
color code (with “?” allowed for
unreadable characters), we don't need to check all that. We
can treat the field as an arbitrary string of any number of
characters in that set. The class attribute COLOR_PAT describes just that; the re.IGNORECASE flag tells the regular expression to be
case-insensitive.
# - - - C o l o r B a n d s F i e l d . s c a n F i e l d - - -
COLOR_PAT = re.compile ( r'[KWRGYBOMS?/ ]+', re.IGNORECASE )
# @staticmethod
def scanField ( encounter, scan, fieldName ):
"""Scan a color-bands field.
"""
#-- 1 --
# [ if scan starts with a pattern that matches
# self.COLOR_PAT ->
# scan := scan advanced past that pattern
# colors := that pattern, uppercased
# else ->
# Log() +:= error message(s)
# raise SyntaxError ]
m = scan.tabReMatch ( ColorBandsField.COLOR_PAT )
if m is None:
scan.syntax ( "Expecting a color-band group." )
else:
colors = m.group().upper()
#-- 2 --
# [ if len(colors) <= COLOR_BANDS_L ->
# self.(COLOR_BANDS_ATTR) := colors, right-filled
# to size COLOR_BANDS_L
# else ->
# Log() +:= error message(s)
# raise SyntaxError ]
if len ( colors ) <= COLOR_BANDS_L:
setattr ( encounter, COLOR_BANDS_ATTR,
ColorBandsField ( encounter, colors ) )
else:
scan.syntax ( "Color-band field '%s' too long; no more "
"than %d characters." %
(colors, COLOR_BANDS_L) )
scanField = staticmethod ( scanField )