Source code for cltk.prosody.lat.scansion_formatter

"""Utility class for formatting scansion patterns"""

import logging

from cltk.prosody.lat.scansion_constants import ScansionConstants

LOG = logging.getLogger(__name__)
LOG.addHandler(logging.NullHandler())

__author__ = ["Todd Cook <todd.g.cook@gmail.com>"]
__license__ = "MIT License"


[docs]class ScansionFormatter: """ Users can specify which scansion symbols to use in the formatting. >>> print(ScansionFormatter().hexameter( "-UU-UU-UU---UU--")) -UU|-UU|-UU|--|-UU|-- >>> constants = ScansionConstants(unstressed="˘", \ stressed= "¯", optional_terminal_ending="x") >>> formatter = ScansionFormatter(constants) >>> print(formatter.hexameter( "¯˘˘¯˘˘¯˘˘¯¯¯˘˘¯¯")) ¯˘˘|¯˘˘|¯˘˘|¯¯|¯˘˘|¯¯ """ def __init__(self, constants=ScansionConstants()): self.constants = constants self.stress_accent_dict = dict( zip( list(self.constants.VOWELS + self.constants.ACCENTED_VOWELS), list(self.constants.ACCENTED_VOWELS + self.constants.ACCENTED_VOWELS), ) )
[docs] def hexameter(self, line: str) -> str: """ Format a string of hexameter metrical stress patterns into foot divisions :param line: the scansion pattern :return: the scansion string formatted with foot breaks >>> print(ScansionFormatter().hexameter( "-UU-UU-UU---UU--")) -UU|-UU|-UU|--|-UU|-- """ mylist = list(line) items = len(mylist) idx_start = items - 2 idx_end = items while idx_start > 0: potential_foot = "".join(mylist[idx_start:idx_end]) if ( potential_foot == self.constants.HEXAMETER_ENDING or potential_foot == self.constants.SPONDEE ): mylist.insert(idx_start, self.constants.FOOT_SEPARATOR) idx_start -= 1 idx_end -= 2 if potential_foot == self.constants.DACTYL: mylist.insert(idx_start, "|") idx_start -= 1 idx_end -= 3 idx_start -= 1 return "".join(mylist)
[docs] def merge_line_scansion(self, line: str, scansion: str) -> str: """ Merge a line of verse with its scansion string. Do not accent dipthongs. :param line: the original Latin verse line :param scansion: the scansion pattern :return: the original line with the scansion pattern applied via macrons >>> print(ScansionFormatter().merge_line_scansion( ... "Arma virumque cano, Troiae qui prīmus ab ōrīs", ... "- U U - U U - UU- - - U U - -")) Ārma virūmque canō, Troiae quī prīmus ab ōrīs >>> print(ScansionFormatter().merge_line_scansion( ... "lītora, multum ille et terrīs iactātus et alto", ... " - U U - - - - - - - U U - U")) lītora, mūltum īlle ēt tērrīs iāctātus et ālto >>> print(ScansionFormatter().merge_line_scansion( ... 'aut facere, haec a te dictaque factaque sunt', ... ' - U U - - - - U U - U U - ')) aut facere, haec ā tē dīctaque fāctaque sūnt """ letters = list(line) marks = list(scansion) if len(scansion) < len(line): marks += ((len(line) - len(scansion)) * " ").split() for idx in range(0, len(marks)): if marks[idx] == self.constants.STRESSED: vowel = letters[idx] if vowel not in self.stress_accent_dict: LOG.error( "problem! vowel: {} not in dict for line {}".format(vowel, line) ) pass else: if idx > 1: if (letters[idx - 2] + letters[idx - 1]).lower() == "qu": new_vowel = self.stress_accent_dict[vowel] letters[idx] = new_vowel continue if idx > 0: if letters[idx - 1] + vowel in self.constants.DIPTHONGS: continue new_vowel = self.stress_accent_dict[vowel] letters[idx] = new_vowel else: new_vowel = self.stress_accent_dict[vowel] letters[idx] = new_vowel return "".join(letters).rstrip()