From bda60a3997935ee351726fcb7c7e878bd5038294 Mon Sep 17 00:00:00 2001 From: Malcolm Sailor Date: Thu, 22 Sep 2022 10:55:46 -0400 Subject: [PATCH 1/2] write out repeat bars and measure suffixes like m1a --- music21/romanText/writeRoman.py | 55 ++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/music21/romanText/writeRoman.py b/music21/romanText/writeRoman.py index 0d378be45c..bb28342430 100644 --- a/music21/romanText/writeRoman.py +++ b/music21/romanText/writeRoman.py @@ -13,10 +13,12 @@ ''' import fractions +import textwrap import unittest import typing as t +from music21 import bar from music21 import base from music21 import metadata from music21 import meter @@ -255,19 +257,45 @@ def prepSequentialListOfLines(self): msg = f'further time signature change(s) unprocessed: {unprocessedTSs}' self.combinedList.append(f'Note: {msg}') + measureNumberString = str(thisMeasure.measureNumber) + if thisMeasure.numberSuffix is not None: + measureNumberString += thisMeasure.numberSuffix + # RomanNumerals measureString = '' # Clear for each measure rnsThisMeasure = thisMeasure.getElementsByClass(roman.RomanNumeral) + if (isinstance(thisMeasure.leftBarline, bar.Repeat) + and thisMeasure.leftBarline.direction == 'start'): + measureString = rnString(measureNumber=measureNumberString, + beat=1.0, + chordString='||:', + inString=measureString, + ) for rn in rnsThisMeasure: if rn.tie is None or rn.tie.type == 'start': # Ignore tied to Roman numerals chordString = self.getChordString(rn) - measureString = rnString(measureNumber=thisMeasure.measureNumber, # Suffix? + measureString = rnString(measureNumber=measureNumberString, beat=rn.beat, chordString=chordString, inString=measureString, # Creating update ) + if (isinstance(thisMeasure.rightBarline, bar.Repeat) + and thisMeasure.rightBarline.direction == 'end'): + # we want to put the repeat at the beat of the last roman + # numeral to avoid printing an unnecessary indication like + # 'b3' prior to the repeat + last_rn = thisMeasure[roman.RomanNumeral].last() + if last_rn is None: + beat = 1.0 + else: + beat = last_rn.beat + measureString = rnString(measureNumber=measureNumberString, + beat=beat, + chordString=':||', + inString=measureString, + ) if measureString: self.combinedList.append(measureString) @@ -332,11 +360,14 @@ def rnString(measureNumber: int, ''' if inString: - inStringMeasureNumber = int(inString.split(' ')[0][1:]) - if inStringMeasureNumber != measureNumber: + inStringMeasureNumber = inString.split(' ')[0][1:] + # inStringMeasureNumber was previously cast to int, but this fails on + # measures with suffixes ("m1a"). However, now we need to cast + # measureNumber to string in the following comparison. + if inStringMeasureNumber != str(measureNumber): msg = f'The current measureNumber is given as {measureNumber}, but ' msg += f'the contextual inString ({inString}) refers to ' - msg += 'measure number {measureNumber}. They should match.' + msg += f'measure number {measureNumber}. They should match.' raise ValueError(msg) else: # inString and therefore start new line inString = f'm{measureNumber}' @@ -542,6 +573,22 @@ def testTypeParses(self): rn = roman.RomanNumeral('viio6', 'G') RnWriter(rn) # and even (perhaps dubiously) directly on other music21 objects + def testRepeats(self): + from music21 import converter + rntxt = textwrap.dedent(''' + Time Signature: 2/4 + m1 ||: C: I + m2 V :|| + m3 ||: I :|| + m4 ||: I + m5a V :|| + m5b I + ''') + s = converter.parse(rntxt, format='romanText') + writer = RnWriter(s) + assert '\n'.join(writer.combinedList).strip().endswith(rntxt.strip()) + + # ------------------------------------------------------------------------------ def testRnString(self): From 50bde53bc5a0e9ac6edc4230a63b1c9ccc392f8e Mon Sep 17 00:00:00 2001 From: Malcolm Sailor Date: Fri, 23 Sep 2022 07:06:54 -0400 Subject: [PATCH 2/2] fix type annotation --- music21/romanText/writeRoman.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/music21/romanText/writeRoman.py b/music21/romanText/writeRoman.py index bb28342430..6be8989ed4 100644 --- a/music21/romanText/writeRoman.py +++ b/music21/romanText/writeRoman.py @@ -331,7 +331,7 @@ def getChordString(self, # ------------------------------------------------------------------------------ -def rnString(measureNumber: int, +def rnString(measureNumber: t.Union[int, str], beat: t.Union[str, int, float, fractions.Fraction], chordString: str, inString: t.Optional[str] = ''):