in moonlight/evaluation/musicxml.py [0:0]
def _build_attributes(self, staff_num, orig_measure):
"""Builds a new <attributes> tag for the given measure.
If the measure already contains an <attributes> tag, all children are copied
as long as they do not have a <staff> tag that's incompatible with the given
staff number.
If the existing <attributes> don't contain a <divisions> tag, we take the
most recent <divisions> from any measure on any part. The <divisions> tag is
required at the start of the score.
Args:
staff_num: Index of the staff across all parts.
orig_measure: The original <measure> tag, which may or may not contain its
own <attributes>.
Returns:
A new <attributes> tag, keeping any applicable attributes from
`orig_measure`, and the most recent <divisions>.
"""
new_attributes = etree.Element('attributes')
orig_attributes = orig_measure.find('attributes')
if orig_attributes is not None:
for attribute in orig_attributes:
new_attribute = _filter_for_staff(staff_num, attribute)
if new_attribute is not None:
new_attributes.append(new_attribute)
# Look for the most recent "divisions" tag.
def find_divisions():
divisions = None
for part in orig_measure.getparent().getparent().findall('part'):
for prev_measure in part.findall('measure'):
prev_attrs = prev_measure.find('attributes')
if (prev_attrs is not None and
prev_attrs.find('divisions') is not None):
divisions = prev_attrs.find('divisions')
if prev_measure is orig_measure:
# Done.
if divisions is None:
raise ValueError('<divisions> is required')
# Copy the tag, or else when appending the tag to a new element, it
# will be deleted from the old element.
return copy.deepcopy(divisions)
if new_attributes.find('divisions') is None:
new_attributes.append(find_divisions())
return new_attributes