def _move_consonant(self, letters: list, positions: list) -> list: """Given a list of consonant positions, move the consonants according to certain consonant syllable behavioral rules for gathering and grouping.""" for pos in positions: previous_letter = letters[pos - 1] consonant = letters[pos] next_letter = letters[pos + 1] if self._contains_vowels(next_letter) and self._starts_with_vowel( next_letter): return StringUtils.move_consonant_right(letters, [pos]) if self._contains_vowels( previous_letter) and self._ends_with_vowel( previous_letter) and len(previous_letter) == 1: return StringUtils.move_consonant_left(letters, [pos]) if previous_letter + consonant in self.constants.ASPIRATES: return StringUtils.move_consonant_left(letters, [pos]) if consonant + next_letter in self.constants.ASPIRATES: return StringUtils.move_consonant_right(letters, [pos]) if next_letter[0] == consonant: return StringUtils.move_consonant_left(letters, [pos]) if consonant in self.constants.MUTES and next_letter[ 0] in self.constants.LIQUIDS: return StringUtils.move_consonant_right(letters, [pos]) if consonant in ['k', 'K'] and next_letter[0] in ['w', 'W']: return StringUtils.move_consonant_right(letters, [pos]) if self._contains_consonants( next_letter[0]) and self._starts_with_vowel( previous_letter[-1]): return StringUtils.move_consonant_left(letters, [pos]) # fall through case if self._contains_consonants(next_letter[0]): return StringUtils.move_consonant_right(letters, [pos]) return letters
def _move_consonant(self, letters: list, positions: list) -> list: """Given a list of consonant positions, move the consonants according to certain consonant syllable behavioral rules for gathering and grouping.""" for pos in positions: previous_letter = letters[pos - 1] consonant = letters[pos] next_letter = letters[pos + 1] if self._contains_vowels(next_letter) and self._starts_with_vowel(next_letter): return StringUtils.move_consonant_right(letters, [pos]) if self._contains_vowels(previous_letter) and self._ends_with_vowel( previous_letter) and len(previous_letter) == 1: return StringUtils.move_consonant_left(letters, [pos]) if previous_letter + consonant in self.constants.ASPIRATES: return StringUtils.move_consonant_left(letters, [pos]) if consonant + next_letter in self.constants.ASPIRATES: return StringUtils.move_consonant_right(letters, [pos]) if next_letter[0] == consonant: return StringUtils.move_consonant_left(letters, [pos]) if consonant in self.constants.MUTES and next_letter[0] in self.constants.LIQUIDS: return StringUtils.move_consonant_right(letters, [pos]) if consonant in ['k', 'K'] and next_letter[0] in ['w', 'W']: return StringUtils.move_consonant_right(letters, [pos]) if self._contains_consonants(next_letter[0]) and self._starts_with_vowel( previous_letter[-1]): return StringUtils.move_consonant_left(letters, [pos]) # fall through case if self._contains_consonants(next_letter[0]): return StringUtils.move_consonant_right(letters, [pos]) return letters
def _process(self, word: str) -> list: """Process a word into a list of strings representing the syllables of the word. This method describes rules for consonant grouping behaviors and then iteratively applies those rules the list of letters that comprise the word, until all the letters are grouped into appropriate syllable groups.""" # if a blank arrives from splitting, just return an empty list if len(word.strip()) == 0: return [] word = self.convert_consonantal_i(word) my_word = " " + word + " " letters = list(my_word) positions = [] for dipth in self.diphthongs: if dipth in my_word: dipth_matcher = re.compile("{}".format(dipth)) matches = dipth_matcher.finditer(my_word) for match in matches: (start, end) = match.span() positions.append(start) matches = self.kw_matcher.finditer(my_word) for match in matches: (start, end) = match.span() positions.append(start) letters = StringUtils.merge_next(letters, positions) letters = StringUtils.remove_blanks(letters) positions.clear() if not self._contains_vowels("".join(letters)): return ["".join(letters).strip() ] # occurs when only 'qu' appears by ellision positions = self._starting_consonants_only(letters) while len(positions) > 0: letters = StringUtils.move_consonant_right(letters, positions) letters = StringUtils.remove_blanks(letters) positions = self._starting_consonants_only(letters) positions = self._ending_consonants_only(letters) while len(positions) > 0: letters = StringUtils.move_consonant_left(letters, positions) letters = StringUtils.remove_blanks(letters) positions = self._ending_consonants_only(letters) positions = self._find_solo_consonant(letters) while len(positions) > 0: letters = self._move_consonant(letters, positions) letters = StringUtils.remove_blanks(letters) positions = self._find_solo_consonant(letters) positions = self._find_consonant_cluster(letters) while len(positions) > 0: letters = self._move_consonant(letters, positions) letters = StringUtils.remove_blanks(letters) positions = self._find_consonant_cluster(letters) return letters
def _process(self, word: str) -> list: """Process a word into a list of strings representing the syllables of the word. This method describes rules for consonant grouping behaviors and then iteratively applies those rules the list of letters that comprise the word, until all the letters are grouped into appropriate syllable groups.""" # if a blank arrives from splitting, just return an empty list if len(word.strip()) == 0: return [] my_word = " " + word + " " letters = list(my_word) positions = [] for dipth in self.diphthongs: if dipth in my_word: dipth_matcher = re.compile("{}".format(dipth)) matches = dipth_matcher.finditer(my_word) for match in matches: (start, end) = match.span() positions.append(start) matches = self.kw_matcher.finditer(my_word) for match in matches: (start, end) = match.span() positions.append(start) letters = StringUtils.merge_next(letters, positions) letters = StringUtils.remove_blanks(letters) positions.clear() if not self._contains_vowels("".join(letters)): return ["".join(letters).strip()] # occurs when only 'qu' appears by ellision positions = self._starting_consonants_only(letters) while len(positions) > 0: letters = StringUtils.move_consonant_right(letters, positions) letters = StringUtils.remove_blanks(letters) positions = self._starting_consonants_only(letters) positions = self._ending_consonants_only(letters) while len(positions) > 0: letters = StringUtils.move_consonant_left(letters, positions) letters = StringUtils.remove_blanks(letters) positions = self._ending_consonants_only(letters) positions = self._find_solo_consonant(letters) while len(positions) > 0: letters = self._move_consonant(letters, positions) letters = StringUtils.remove_blanks(letters) positions = self._find_solo_consonant(letters) positions = self._find_consonant_cluster(letters) while len(positions) > 0: letters = self._move_consonant(letters, positions) letters = StringUtils.remove_blanks(letters) positions = self._find_consonant_cluster(letters) return letters
def get_syllable_count(self, syllables: list) -> int: """Counts the number of syllable groups that would occur after ellision. Often we will want preserve the position and separation of syllables so that they can be used to reconstitute a line, and apply stresses to the original word positions. However, we also want to be able to count the number of syllables accurately. >>> syllabifier = Syllabifier() >>> print(syllabifier.get_syllable_count([ ... 'Jām', 'tūm', 'c', 'au', 'sus', 'es', 'u', 'nus', 'I', 'ta', 'lo', 'rum'])) 11 """ tmp_syllables = copy.deepcopy(syllables) return len(StringUtils.remove_blank_spaces( StringUtils.move_consonant_right(tmp_syllables, self._find_solo_consonant(tmp_syllables))))