Example #1
0
def sources_and_editors(MEI_tree, alternates_data):
    """add the sourceDesc element, the source elements, and
    the editor elements to the mei header
    """
    def add_source(sourceDesc, adi):
        existing = sourceDesc.getDocument().getElementById(adi[3])
        if not existing:
            source = MeiElement('source')
            source.id = adi[3]
            source.addAttribute('type', adi[1])
            sourceDesc.addChild(source)

    def add_editor(titleStmt, ali):
        existing = titleStmt.getDocument().getElementById(adi[3])
        if not existing:
            editor = MeiElement('editor')
            editor.id = ali[3]
            # Using 'replace' simply to have more natural name for a person
            editor.addAttribute('type', adi[1].replace('ction', 'ctor'))
            titleStmt.addChild(editor)

    for adi in alternates_data:
        if adi[1] == RECONSTRUCTION:
            add_editor(chain_elems(MEI_tree, ['meiHead', 'fileDesc', 'titleStmt']), adi)
        elif adi[1] == EMENDATION:
            add_editor(chain_elems(MEI_tree, ['meiHead', 'fileDesc', 'titleStmt']), adi)
        elif adi[1] == CONCORDANCE:
            add_source(chain_elems(MEI_tree, ['meiHead', 'fileDesc', 'sourceDesc']), adi)
        elif adi[0] != adi[2] and adi[1] == VARIANT:
            add_source(chain_elems(MEI_tree, ['meiHead', 'fileDesc', 'sourceDesc']), adi)
        else:
            pass
Example #2
0
def sources_and_editors(MEI_tree, alternates_data):
	"""add the sourceDesc element, the source elements, and 
	the editor elements to the mei header
	"""	
	def add_source(sourceDesc, adi):
		existing = sourceDesc.getDocument().getElementById(adi[3])
		if not existing:
			source = MeiElement('source')
			source.id = adi[3]
			sourceDesc.addChild(source)

	def add_editor(titleStmt, ali):
		existing = titleStmt.getDocument().getElementById(adi[3])
		if not existing:
			editor = MeiElement('editor')
			editor.id = ali[3]
			titleStmt.addChild(editor)

	for adi in alternates_data:
		if adi[1] == RECONSTRUCTION or adi[1] == EMENDATION:
			add_editor(chain_elems(MEI_tree, ['meiHead', 'fileDesc', 'titleStmt']), adi)
		if adi[0] != adi[2] and adi[1] == VARIANT:
			add_source(chain_elems(MEI_tree, ['meiHead', 'fileDesc', 'sourceDesc']), adi)
Example #3
0
def orig_clefs(MEI_tree, alternates_list):
    def is_placeholder(staff_n, alternates_list):
        """A staff is PLACEHOLDER if there's at least one other
        staff that is a reconstruction or concordance of it.
        """
        for a in alternates_list:
            # if a is reconstruction of alt_list_item:
            if a[2] == staff_n and a[1] in (RECONSTRUCTION, CONCORDANCE):
                return True
        return False

    def staff_role(staff_n, alternates_list):
        for a in alternates_list:
            if a[0] == staff_n:
                return a[1]

    def mergeClefAttributes(staffDef, clef):
        # merge the following attributes:
        #  * shape
        #  * line
        #  * oct
        #  * dis
        #  * dis.place
        def mergeAttr(attr_name):
            if (clef.hasAttribute(attr_name)):
                staffDef.addAttribute('clef.' + attr_name,
                                      clef.getAttribute(attr_name).getValue()
                                      )
        mergeAttr('shape')
        mergeAttr('line')
        mergeAttr('oct')
        mergeAttr('dis')
        mergeAttr('dis.place')

    def mergeScoreDefAttributes(scoreDef1, scoreDef2):
        # merge the following attributes:
        #  * meter.count
        #  * meter.unit
        #  * meter.sym
        #  * clef.line
        #  * clef.shape
        #  * clef.oct
        #  * clef.dis
        #  * clef.dis.place
        #  * key.sig
        #  * key.pname
        #  * key.accid
        #  * key.mode
        #  * key.sig.mixed

        def mergeAttr(attr_name):
            if (scoreDef2.hasAttribute(attr_name)):
                scoreDef1.addAttribute(attr_name, scoreDef2.getAttribute(attr_name).getValue())
        mergeAttr('meter.count')
        mergeAttr('meter.unit')
        mergeAttr('meter.sym')
        mergeAttr('clef.line')
        mergeAttr('clef.oct')
        mergeAttr('clef.dis')
        mergeAttr('clef.dis.place')
        mergeAttr('key.sig')
        mergeAttr('key.pname')
        mergeAttr('key.accid')
        mergeAttr('key.mode')
        mergeAttr('key.sig.mixed')

    # copy initial scoreDef to meiHead/workDesc/work/incip/score/
    scoreDefs = get_descendants(MEI_tree, 'scoreDef')
    # make a copy of the main scoreDef
    mainScoreDef = MeiElement(scoreDefs[0])
    # remove unwanted staves:
    #  - Reconstructed (placeholder) staves
    #  - Reconstruction (actual reconstruction) staves
    #  - Emendation staves
    staffDefs = get_descendants(mainScoreDef, 'staffDef')
    for staffDef in staffDefs:
        staff_n = staffDef.getAttribute('n').getValue()
        if (is_placeholder(staff_n, alternates_list) or
                staff_role(staff_n, alternates_list) in (RECONSTRUCTION, EMENDATION, CONCORDANCE)):
            staffDef.parent.removeChild(staffDef)
    meiHead = get_descendants(MEI_tree, 'meiHead')[0]

    head_score = chain_elems(meiHead, ['workDesc', 'work', 'incip', 'score'])
    head_score.addChild(mainScoreDef)

    # remove the milestone scoreDef and update the
    # main scoreDef accordingly, and:
    #  1. find <clef> elements (they should be in the first measure:
    #     assert this, and signal warning if it's not the case)
    #  2. update main scoreDef according to <clef>s

    music = get_descendants(MEI_tree, 'music')[0]
    section = music.getDescendantsByName('section')[0]

    mainScoreDef = music.getDescendantsByName('scoreDef')[0]
    i = 0
    for scoreDef in music.getDescendantsByName('scoreDef'):
        # Choosing 3 as a convenient value for a measure early
        # in the piece, hence unlikely to give false positives,
        # with a little wiggle room
        if i > 0 and measures_before_element(scoreDef) < 3:
            mergeScoreDefAttributes(mainScoreDef, scoreDef)
            scoreDef.getParent().removeChild(scoreDef)
        i += 1

    clefs = section.getDescendantsByName('clef')
    for clef in clefs:
        clef_in_measure = False
        clef_in_staff = False
        if clef.hasAncestor('measure'):
            measure = clef.getAncestor('measure')
            if (measure.hasAttribute('n') and
                    measure.getAttribute('n').getValue() == '1'):
                clef_in_measure = True
        if clef.hasAncestor('staff'):
            staff = clef.getAncestor('staff')
            clef_in_staff = True

        if not clef_in_measure:
            logging.warning("<clef> is only valid under the first <measure>.")
            # continue

        if not clef_in_staff:
            logging.warning("<clef> is only valid under a <staff>.")
            # continue

        if staff.hasAttribute('n'):
            clef_staff_n = staff.getAttribute('n').getValue()
        else:
            clef_staff_n = '1'

        staffDefs = music.getDescendantsByName('staffDef')
        for staffDef in staffDefs:
            staff_n = staffDef.getAttribute('n').getValue()
            if (staff_n == clef_staff_n):
                mergeClefAttributes(staffDef, clef)