A decorator for phonemes, used in applying rules over words.
	Returns a copy of the input phoneme, with additional attributes,
	specifying whether the phoneme occurs at a word or syllable boundary,
	or its position in an environment.
432829
def PositionedPhoneme(phoneme, 
	word_initial = False, word_final = False, 
	syllable_initial = False, syllable_final = False,
	env_start = False, env_end = False):
	'''
	
	'''
	
	pos_phoneme = deepcopy(phoneme)
	pos_phoneme.word_initial = word_initial
	pos_phoneme.word_final = word_final
	pos_phoneme.syllable_initial = syllable_initial
	pos_phoneme.syllable_final = syllable_final
	pos_phoneme.env_start = env_start
	pos_phoneme.env_end = env_end

	return pos_phoneme
101866
def T6(word, rules):
    ''''''
    offset = 0

    try:
        WORD, rest = tuple(word.split('.', 1))

        for vvv in long_vowel_sequences(rest):
            i = vvv.start(2)
            vvv = vvv.group(2)
            i += (2 if phon.is_long(vvv[:2]) else 1) + offset
            rest = rest[:i] + '.' + rest[i:]
            offset += 1

    except ValueError:
        WORD = word

    for vvv in long_vowel_sequences(WORD):
        i = vvv.start(2) + 2
        WORD = WORD[:i] + '.' + WORD[i:]

    try:
        WORD += '.' + rest

    except UnboundLocalError:
        pass

    rules += ' T6' if word != WORD else ''

    return WORD, rules
399625
def _romanize(word: str) -> str:
    
    if not isinstance(word, str) or not word:
        return ""

    word = _replace_vowels(_normalize(word))
    res = _RE_CONSONANT.findall(word)

    # 2-character word, all consonants
    if len(word) == 2 and len(res) == 2:
        word = list(word)
        word.insert(1, "o")
        word = "".join(word)

    word = _replace_consonants(word, res)

    return word
557307
def _syllable_condenser(self, words_syllables):
        

        sentences_syllables = []
        for sentence in words_syllables:
            syllables_sentence = []
            for word in sentence:
                syllables_sentence += word
            sentences_syllables.append(syllables_sentence)
        return sentences_syllables
40798
def _long_by_nature(self, syllable):
        

        # Find diphthongs
        vowel_group = ''
        for char in syllable:
            if char in self.long_vowels:
                return True
            elif char not in self.sing_cons:
                vowel_group += char

        if vowel_group in self.diphthongs:
            return True
677853
def wsp(word):
    ''''''
    HEAVY = r'[ieaAoO]{1}[\.]*(u|y)[^ieaAoO]+(\.|$)'

    # # if the word is not monosyllabic, lop off the final syllable, which is
    # # extrametrical
    # if '.' in word:
    #     word = word[:word.rindex('.')]

    # gather the indices of syllable boundaries
    delimiters = [i for i, char in enumerate(word) if char == '.']

    if len(delimiters) % 2 != 0:
        delimiters.append(len(word))

    unstressed = []

    # gather the indices of unstressed positions
    for i, d in enumerate(delimiters):
        if i % 2 == 0:
            unstressed.extend(range(d + 1, delimiters[i + 1]))

    # find the number of unstressed heavy syllables
    heavies = re.finditer(HEAVY, word)
    violations = sum(1 for m in heavies if m.start(0) in unstressed)

    return violations
280971
def get_phonetic_feature_vector(self, c, lang):
        """"""

        offset = self.get_offset(c, lang)
        if not self.in_coordinated_range_offset(offset):
            return self.invalid_vector()

        phonetic_data, phonetic_vectors = self.get_phonetic_info(lang)

        # 'Valid Vector Representation' is the [5] column
        if phonetic_data[offset][5] == 0:
            return self.invalid_vector()

        return phonetic_vectors[offset]
390129
def apply(self, word, ctx=None):
        
        chars = get_letters(word)
        flag = True #no error assumed
        reason = None #no reason
        prev_char = None

        for char in chars:
            rule1,rule2,rule3 = False,False,False
            # rule 1 : uyir followed by kombugal
            rule1 = (char[-1] in utf8.accent_symbols) and (char[0] in utf8.uyir_letters)
            if not rule1:
                # rule 2 : two pullis adjacent to each other
                rule2 = len(char) >= 2 and (char[-1] == utf8.pulli_symbols[0]) and (char[-2] == char[-1] )
                if not rule2:
                    # rule 3 : none of the accent symbols repeat
                    # exclusions to rule 3 : non-standard Unicode encoding of periya kombu / siriya kombu with thunai kaal
                    rule3 =  len(char) >= 2 and (char[-1] in utf8.accent_symbols) and (char[-2] in utf8.accent_symbols) \
                    and not( char[-1] == u"ா" and char[-2] in [u"ெ",u"ே"])

            if rule1 or rule2 or rule3:
                flag = False
                reason = BadIME.reason
                break
            prev_char = char # continue loop
        #print([flag,reason])
        return flag,reason
16233
def getNumPhones(isleDict, word, maxFlag):
    '''
    
    '''
    phoneCount = 0
    syllableCount = 0
    
    syllableCountList = []
    phoneCountList = []
    
    wordList = isleDict.lookup(word)
    entryList = zip(*wordList)
    
    for lookupResultList in entryList:
        syllableList = []
        for wordSyllableList in lookupResultList:
            syllableList.extend(wordSyllableList)
        
        syllableCountList.append(len(syllableList))
        phoneCountList.append(len([phon for phoneList in syllableList for
                                   phon in phoneList]))
    
    # The average number of phones for all possible pronunciations
    #    of this word
    if maxFlag is True:
        syllableCount += max(syllableCountList)
        phoneCount += max(phoneCountList)
    else:
        syllableCount += (sum(syllableCountList) /
                          float(len(syllableCountList)))
        phoneCount += sum(phoneCountList) / float(len(phoneCountList))
    
    return syllableCount, phoneCount
1295847
def scan_text(self, input_string):
        
        syllables = self._make_syllables(input_string)
        sentence_syllables = self._syllable_condenser(syllables)
        meter = self._scansion(sentence_syllables)
        return meter
1199799
def _repeat_word(word, N, word_space=" "):
    
    message = (word_space + word) * N
    message = message[len(word_space):]
    return message
115853
def to_phonetics(self):
        
        if len(self.long_lines) == 0:
            logger.error("No text was imported")
            self.syllabified_text = []
        else:
            transcriber = Transcriber(DIPHTHONGS_IPA, DIPHTHONGS_IPA_class, IPA_class, old_norse_rules)
            transcribed_text = []
            phonological_features_text = []
            for i, long_line in enumerate(self.long_lines):
                transcribed_text.append([])
                phonological_features_text.append([])
                for short_line in long_line:
                    assert isinstance(short_line, ShortLine) or isinstance(short_line, LongLine)
                    short_line.to_phonetics(transcriber)
                    transcribed_text[i].append(short_line.transcribed)
                    phonological_features_text[i].append(short_line.phonological_features_text)

            self.transcribed_text = transcribed_text
            self.phonological_features_text = phonological_features_text
558593
def syllabify(word):
    ''''''
    compound = bool(re.search(r'(-| |=)', word))
    syllabify = _syllabify_compound if compound else _syllabify_simplex
    syllabifications = list(syllabify(word))

    for word, rules in rank(syllabifications):
        # post-process
        word = str(replace_umlauts(word, put_back=True))
        rules = rules[1:]

        yield word, rules
287509
def rule_for(self, target_class):
        
        def decorator(rule_class):
            self.add_rule(rule_class, target_class)
            return rule_class
        return decorator
108014
def transcribe(self, text, as_phonemes = False):
		'''
		
		'''
		phoneme_words = [self.transcribe_word(word) for word in self._tokenize(text)]
		if not as_phonemes:
			words = [''.join([phoneme.ipa for phoneme in word]) for word in phoneme_words]
			return ' '.join(words)
		else:
			return phoneme_words
670324
def preprocess_na(sent, label_type):
    
    if label_type == "phonemes_and_tones":
        phonemes = True
        tones = True
        tgm = True
    elif label_type == "phonemes_and_tones_no_tgm":
        phonemes = True
        tones = True
        tgm = False
    elif label_type == "phonemes":
        phonemes = True
        tones = False
        tgm = False
    elif label_type == "tones":
        phonemes = False
        tones = True
        tgm = True
    elif label_type == "tones_notgm":
        phonemes = False
        tones = True
        tgm = False
    else:
        raise ValueError("Unrecognized label type: %s" % label_type)

    def pop_phoneme(sentence):
        """Pop phonemes off a sentence one at a time"""
        # TODO desperately needs refactoring

        # Treating fillers as single tokens; normalizing to əəə and mmm
        if phonemes:
            if sentence[:4] in ["əəə…", "mmm…"]:
                return sentence[:4], sentence[4:]
            if sentence.startswith("ə…"):
                return "əəə…", sentence[2:]
            if sentence.startswith("m…"):
                return "mmm…", sentence[2:]
            if sentence.startswith("mm…"):
                return "mmm…", sentence[3:]

        # Normalizing some stuff
        if sentence[:3] == "wæ̃":
            if phonemes:
                return "w̃æ", sentence[3:]
            else:
                return None, sentence[3:]
        if sentence[:3] == "ṽ̩":
            if phonemes:
                return "ṽ̩", sentence[3:]
            else:
                return None, sentence[3:]

        if sentence[:3] in TRI_PHNS:
            if phonemes:
                return sentence[:3], sentence[3:]
            else:
                return None, sentence[3:]
        if sentence[:2] in BI_PHNS:
            if phonemes:
                return sentence[:2], sentence[2:]
            else:
                return None, sentence[2:]
        if sentence[:2] == "˧̩":
            return "˧", sentence[2:]
        if sentence[:2] == "˧̍":
            return "˧", sentence[2:]
        if sentence[0] in UNI_PHNS:
            if phonemes:
                return sentence[0], sentence[1:]
            else:
                return None, sentence[1:]
        if sentence[:2] in BI_TONES:
            if tones:
                return sentence[:2], sentence[2:]
            else:
                return None, sentence[2:]
        if sentence[0] in UNI_TONES:
            if tones:
                return sentence[0], sentence[1:]
            else:
                return None, sentence[1:]
        if sentence[0] in MISC_SYMBOLS:
            # We assume these symbols cannot be captured.
            return None, sentence[1:]
        if sentence[0] in BAD_NA_SYMBOLS:
            return None, sentence[1:]
        if sentence[0] in PUNC_SYMBOLS:
            return None, sentence[1:]
        if sentence[0] in ["-", "ʰ", "/"]:
            return None, sentence[1:]
        if sentence[0] in set(["<", ">"]):
            # We keep everything literal, thus including what is in <>
            # brackets; so we just remove these tokens"
            return None, sentence[1:]
        if sentence[0] == "[":
            # It's an opening square bracket, so ignore everything until we
            # find a closing one.
            if sentence.find("]") == len(sentence)-1:
                # If the closing bracket is the last char
                return None, ""
            else:
                return None, sentence[sentence.find("]")+1:]
        if sentence[0] in set([" ", "\t", "\n"]):
            # Return a space char so that it can be identified in word segmentation
            # processing.
            return " ", sentence[1:]
        if sentence[0] == "|" or sentence[0] == "ǀ" or sentence[0] == "◊":
            # TODO Address extrametrical span symbol ◊ differently. For now,
            # treating it as a tone group boundary marker for consistency with
            # previous work.
            if tgm:
                return "|", sentence[1:]
            else:
                return None, sentence[1:]
        if sentence[0] in "()":
            return None, sentence[1:]
        print("***" + sentence)
        raise ValueError("Next character not recognized: " + sentence[:1])

    def filter_for_phonemes(sentence):
        """ Returns a sequence of phonemes and pipes (word delimiters). Tones,
        syllable boundaries, whitespace are all removed."""

        filtered_sentence = []
        while sentence != "":
            phoneme, sentence = pop_phoneme(sentence)
            if phoneme != " ":
                filtered_sentence.append(phoneme)
        filtered_sentence = [item for item in filtered_sentence if item != None]
        return " ".join(filtered_sentence)

    # Filter utterances with certain words
    if "BEGAIEMENT" in sent:
        return ""
    sent = filter_for_phonemes(sent)
    return sent
143024
def text_to_phonemes(self, word: str) -> list:
        
        phonemes = []
        is_repeted = False
        if len(word) >= 2:
            for index in range(len(word) - 1):
                if is_repeted:
                    is_repeted = False
                    continue
                if word[index:index + 2] in self.diphthongs_ipa:  # diphthongs
                    phonemes.append(self.diphthongs_ipa_class[word[index] + word[index + 1]])
                    is_repeted = True
                elif word[index] == word[index + 1]:
                    phonemes.append(self.ipa_class[word[index]].lengthen())
                    is_repeted = True
                else:
                    phonemes.append(self.ipa_class[word[index]])
            if not is_repeted:
                phonemes.append(self.ipa_class[word[len(word) - 1]])
        else:
            phonemes.append(self.ipa_class[word[0]])
        return phonemes