diff --git a/allzweckmesser/meters.py b/allzweckmesser/meters.py index 92e756aa4a725ccb83f839161c9fc48e9db65323..26785cdb0020766cff12c9eff09ac38a6ff5455c 100644 --- a/allzweckmesser/meters.py +++ b/allzweckmesser/meters.py @@ -119,15 +119,15 @@ ALL_METERS = { 'hendecasyllables': Meter( 'Phalaecian Hendecasyllable', AEOLIC_BASE + r'(–)(â‘)(â‘)(–)(â‘)(–)(â‘)(–)(â‘|–)', - breaks=[[('element', 6, 'After sixth element')]], + breaks=[[('syllable', 6, 'After sixth syllable')]], short_name='hendecasyllables', id=6 ), 'scazon': Meter( 'Choliamb', r'(â‘|–)(–)(â‘)(–)(â‘|–)(–)(â‘)(–)(â‘)(–)(–)(â‘|–)', - breaks=[[('element', 5, 'After sixth element')], - [('element', 7, 'After sixth element')]], + breaks=[[('syllable', 5, 'After fifth syllable')], + [('syllable', 7, 'After seventh syllable')]], short_name='scazon', id=7 ), diff --git a/allzweckmesser/model.py b/allzweckmesser/model.py index b7a302384063d80d389e494fe1fc11c576f46419..40412f05f0dc2582cc7818c4636dd09cbe15fafe 100644 --- a/allzweckmesser/model.py +++ b/allzweckmesser/model.py @@ -575,11 +575,48 @@ class Position: # TODO: Implement this. pass + @classmethod + def after_syllable(cls, reading: Reading, syll_num: int) -> 'Position': + morae = 0 + syllables = 0 + punctuation = '' + for token in reading.tokens: + if token.is_punct(): + punctuation += token.text + for i, syllable in enumerate(token.syllables): + word_boundary = i == 0 + if syllables == syll_num and syllable.syllable_length > 0: + position = cls( + reading=reading, mora=morae, token=token, + syllable=syllable, word_boundary=word_boundary, + punctuation=punctuation + ) + return position + else: + morae += syllable.syllable_length + if syllable.syllable_length > 0: + syllables += 1 + punctuation = '' + else: + # The position has not been found. There are two possibilities: + if syllables == syll_num: + # The position is at the end of the sentence. + position = cls( + reading=reading, mora=morae, token=None, syllable=None, + word_boundary=True, punctuation=punctuation + ) + return position + else: + # There is no syllable boundary at the given syllable. + return None + @classmethod def after(cls, type: str, reading: Reading, position_number: int, meter: '.meters.Meter') -> 'Position': if type == 'mora': return cls.after_mora(reading, position_number) + elif type == 'syllable': + return cls.after_syllable(reading, meter, position_number) elif type == 'element': return cls.after_element(reading, meter, position_number) else: