Пример #1
0
    def accent_by_position(self, verse: str) -> str:
        """:param verse: a line of unaccented hexameter verse
        :return: the same line with vowels accented by position

        >>> print(HexameterScanner().accent_by_position(
        ... "Arma virumque cano, Troiae qui primus ab oris").lstrip())
        Ārma virūmque canō  Trojae quī primus ab oris
        """
        line = verse.translate(self.punctuation_substitutions)
        line = self.transform_i_to_j(line)
        marks = list(line)
        # Vowels followed by 2 consonants
        # The digraphs ch, ph, th, qu and sometimes gu and su count as single consonants.
        # see http://people.virginia.edu/~jdk3t/epicintrog/scansion.htm
        marks = StringUtils.overwrite(
            marks, "[{}][{}][{}]".format(self.constants.VOWELS,
                                         self.constants.CONSONANTS,
                                         self.constants.CONSONANTS_WO_H),
            self.constants.STRESSED)
        # one space (or more for 'dropped' punctuation may intervene)
        marks = StringUtils.overwrite(
            marks, r"[{}][{}]\s*[{}]".format(self.constants.VOWELS,
                                             self.constants.CONSONANTS,
                                             self.constants.CONSONANTS_WO_H),
            self.constants.STRESSED)
        # ... if both consonants are in the next word, the vowel may be long
        # .... but it could be short if the vowel is not on the thesis/emphatic part of the foot
        # ... see Gildersleeve and Lodge p.446
        marks = StringUtils.overwrite(
            marks, r"[{}]\s*[{}][{}]".format(self.constants.VOWELS,
                                             self.constants.CONSONANTS,
                                             self.constants.CONSONANTS_WO_H),
            self.constants.STRESSED)
        #  x is considered as two letters
        marks = StringUtils.overwrite(marks,
                                      "[{}][xX]".format(self.constants.VOWELS),
                                      self.constants.STRESSED)
        #  z is considered as two letters
        marks = StringUtils.overwrite(
            marks, r"[{}][zZ]".format(self.constants.VOWELS),
            self.constants.STRESSED)
        original_verse = list(line)
        for idx, word in enumerate(original_verse):
            if marks[idx] == self.constants.STRESSED:
                original_verse[idx] = self.constants.VOWELS_TO_ACCENTS[
                    original_verse[idx]]
        return "".join(original_verse)
Пример #2
0
    def transform_i_to_j_optional(self, line: str) -> str:
        """Sometimes for the demands of meter a more permissive i to j transformation is warranted.
        :param line:
        :return:

        >>> print(HexameterScanner().transform_i_to_j_optional("Italiam"))
        Italjam
        >>> print(HexameterScanner().transform_i_to_j_optional("Lāvīniaque"))
        Lāvīnjaque
        >>> print(HexameterScanner().transform_i_to_j_optional("omnium"))
        omnjum
        """

        words = line.split(" ")
        space_list = StringUtils.space_list(line)
        corrected_words = []
        for word in words:
            found = False
            for prefix in self.constants.PREFIXES:
                if word.startswith(prefix) and word != prefix:
                    corrected_words.append(
                        self.syllabifier.convert_consonantal_i(prefix))
                    corrected_words.append(
                        self.syllabifier.convert_consonantal_i(
                            word[len(prefix):]))
                    found = True
                    break
            if not found:
                corrected_words.append(
                    self.syllabifier.convert_consonantal_i(word))
        new_line = StringUtils.join_syllables_spaces(corrected_words,
                                                     space_list)
        #  the following two may be tunable and subject to improvement
        char_list = StringUtils.overwrite(
            list(new_line),
            "[bcdfgjkmpqrstvwxzBCDFGHJKMPQRSTVWXZ][i][{}]".format(
                self.constants.VOWELS_WO_I), "j", 1)
        char_list = StringUtils.overwrite(
            char_list, "[{}][iI][{}]".format(self.constants.LIQUIDS,
                                             self.constants.VOWELS_WO_I), "j",
            1)
        return "".join(char_list)
Пример #3
0
    def transform_i_to_j(self, line: str) -> str:
        """Transform instances of consonantal i to j
        :param line:
        :return:

        >>> print(HexameterScanner().transform_i_to_j("iactātus"))
        jactātus
        >>> print(HexameterScanner().transform_i_to_j("bracchia"))
        bracchia
        """

        words = line.split(" ")
        space_list = StringUtils.space_list(line)
        corrected_words = []
        for word in words:
            found = False
            for prefix in self.constants.PREFIXES:
                if word.startswith(prefix) and word != prefix:
                    corrected_words.append(
                        self.syllabifier.convert_consonantal_i(prefix))
                    corrected_words.append(
                        self.syllabifier.convert_consonantal_i(
                            word[len(prefix):]))
                    found = True
                    break
            if not found:
                corrected_words.append(
                    self.syllabifier.convert_consonantal_i(word))
        new_line = StringUtils.join_syllables_spaces(corrected_words,
                                                     space_list)
        char_list = StringUtils.overwrite(
            list(new_line),
            r"\b[iī][{}]".format(self.constants.VOWELS +
                                 self.constants.ACCENTED_VOWELS), "j")
        char_list = StringUtils.overwrite(
            char_list, r"\b[I][{}]".format(self.constants.VOWELS_WO_I), "J")
        char_list = StringUtils.overwrite(
            char_list, r"[{}][i][{}]".format(self.constants.VOWELS_WO_I,
                                             self.constants.VOWELS), "j", 1)
        return "".join(char_list)
Пример #4
0
    def transform_i_to_j_optional(self, line: str) -> str:
        """Sometimes for the demands of meter a more permissive i to j transformation is warranted.
        :param line:
        :return:

        >>> print(VerseScanner().transform_i_to_j_optional("Italiam"))
        Italjam
        >>> print(VerseScanner().transform_i_to_j_optional("Lāvīniaque"))
        Lāvīnjaque
        >>> print(VerseScanner().transform_i_to_j_optional("omnium"))
        omnjum
        """
        words = line.split(" ")
        space_list = StringUtils.space_list(line)
        corrected_words = []
        for word in words:
            found = False
            for prefix in self.constants.PREFIXES:
                if word.startswith(prefix) and word != prefix:
                    corrected_words.append(self.syllabifier.convert_consonantal_i(prefix))
                    corrected_words.append(
                        self.syllabifier.convert_consonantal_i(word[len(prefix):]))
                    found = True
                    break
            if not found:
                corrected_words.append(self.syllabifier.convert_consonantal_i(word))
        new_line = StringUtils.join_syllables_spaces(corrected_words, space_list)
        #  the following two may be tunable and subject to improvement
        char_list = StringUtils.overwrite(list(new_line),
                                          "[bcdfgjkmpqrstvwxzBCDFGHJKMPQRSTVWXZ][i][{}]".format(
                                              self.constants.VOWELS_WO_I),
                                          "j", 1)
        char_list = StringUtils.overwrite(char_list,
                                          "[{}][iI][{}]".format(self.constants.LIQUIDS,
                                                                self.constants.VOWELS_WO_I),
                                          "j", 1)
        return "".join(char_list)
Пример #5
0
    def transform_i_to_j(self, line: str) -> str:
        """Transform instances of consonantal i to j
        :param line:
        :return:

        >>> print(VerseScanner().transform_i_to_j("iactātus"))
        jactātus
        >>> print(VerseScanner().transform_i_to_j("bracchia"))
        bracchia
        """

        words = line.split(" ")
        space_list = StringUtils.space_list(line)
        corrected_words = []
        for word in words:
            found = False
            for prefix in self.constants.PREFIXES:
                if word.startswith(prefix) and word != prefix:
                    corrected_words.append(self.syllabifier.convert_consonantal_i(prefix))
                    corrected_words.append(
                        self.syllabifier.convert_consonantal_i(word[len(prefix):]))
                    found = True
                    break
            if not found:
                corrected_words.append(self.syllabifier.convert_consonantal_i(word))
        new_line = StringUtils.join_syllables_spaces(corrected_words, space_list)
        char_list = StringUtils.overwrite(list(new_line),
                                          r"\b[iī][{}]".format(
                                              self.constants.VOWELS + self.constants.ACCENTED_VOWELS),
                                          "j")
        char_list = StringUtils.overwrite(char_list,
                                          r"\b[I][{}]".format(self.constants.VOWELS_WO_I),
                                          "J")
        char_list = StringUtils.overwrite(char_list, r"[{}][i][{}]".format(
            self.constants.VOWELS_WO_I, self.constants.VOWELS),
                                          "j", 1)
        return "".join(char_list)
Пример #6
0
    def accent_by_position(self, verse_line: str) -> str:
        """Accent vowels according to the rules of scansion.

        :param verse: a line of unaccented verse
        :return: the same line with vowels accented by position

        >>> print(VerseScanner().accent_by_position(
        ... "Arma virumque cano, Troiae qui primus ab oris").lstrip())
        Ārma virūmque canō  Trojae qui primus ab oris
        """
        line = verse_line.translate(self.punctuation_substitutions)
        line = self.transform_i_to_j(line)
        marks = list(line)

        # locate and save dipthong positions since we don't want them being accented
        dipthong_positions = []
        for dipth in self.constants.DIPTHONGS:
            if dipth in line:
                dipthong_positions.append(line.find(dipth))

        # Vowels followed by 2 consonants
        # The digraphs ch, ph, th, qu and sometimes gu and su count as single consonants.
        # see http://people.virginia.edu/~jdk3t/epicintrog/scansion.htm
        marks = StringUtils.overwrite(marks, "[{}][{}][{}]".format(
            self.constants.VOWELS,
            self.constants.CONSONANTS,
            self.constants.CONSONANTS_WO_H),
                                      self.constants.STRESSED)
        # one space (or more for 'dropped' punctuation may intervene)
        marks = StringUtils.overwrite(marks,
                                      r"[{}][{}]\s*[{}]".format(
                                          self.constants.VOWELS,
                                          self.constants.CONSONANTS,
                                          self.constants.CONSONANTS_WO_H),
                                      self.constants.STRESSED)
        # ... if both consonants are in the next word, the vowel may be long
        # .... but it could be short if the vowel is not on the thesis/emphatic part of the foot
        # ... see Gildersleeve and Lodge p.446
        marks = StringUtils.overwrite(marks,
                                      r"[{}]\s*[{}][{}]".format(
                                          self.constants.VOWELS,
                                          self.constants.CONSONANTS,
                                          self.constants.CONSONANTS_WO_H),
                                      self.constants.STRESSED)
        #  x is considered as two letters
        marks = StringUtils.overwrite(marks,
                                      "[{}][xX]".format(self.constants.VOWELS),
                                      self.constants.STRESSED)
        #  z is considered as two letters
        marks = StringUtils.overwrite(marks,
                                      r"[{}][zZ]".format(self.constants.VOWELS),
                                      self.constants.STRESSED)
        original_verse = list(line)
        for idx, word in enumerate(original_verse):
            if marks[idx] == self.constants.STRESSED:
                original_verse[idx] = self.constants.VOWELS_TO_ACCENTS[original_verse[idx]]
        # make sure dipthongs aren't accented
        for idx in dipthong_positions:
            if original_verse[idx + 1] in self.constants.ACCENTS_TO_VOWELS:
                original_verse[idx + 1] = self.constants.ACCENTS_TO_VOWELS[original_verse[idx + 1]]

        return "".join(original_verse)