def isClassV(base): #FIXME does not check if noun """ nouns only: ends with 1 or 2 vowels followed by 'r' """ exp = explode(base) #FIXME: does not check if word is a noun or words marked with '*' isClass = len(exp) > 1 and Syllables.syllableMatches(exp, 'Vr') return isClass
def getSyllableText(word): syl = '' for i in Syllables.getSyllables(word): syl = syl + '\t' + ''.join(i) + '\t/' # remove trailing '/' syl = syl[1:-2] return syl
def hasRhythmicLength(word, index): """ does the sylIndex-th syllable have rhythmic vowel length """ exp = Base.explode(word) syl = Syllables.getSyllables(word) rl = getRhythmicVowelLengthPattern(word) rlexp = [] for s in range(len(syl)): for r in range(len(syl[s])): rlexp.append(rl[s]) return rlexp[index]
def getRhythmicVowelLengthText(word): rhy = '' syls = Syllables.getSyllables(word) rlen = getRhythmicVowelLengthPattern(word) for i in range(len(syls)): if rlen[i]: syls[i] = ''.join(syls[i]) + '\t' rhy = rhy + '\t' + ''.join(syls[i]) + '\t/' # remove trailing '/' rhy = rhy[1:-2] return rhy
def getStressText(word): stress = '' syls = Syllables.getSyllables(word) spat = getStressPattern(word) for i in range(len(syls)): if spat[i]: syls[i] = ''.join(syls[i]).upper() stress = stress + '\t' + ''.join(syls[i]) + '\t/' # remove trailing '/' stress = stress[1:-2] return stress
def getRhythmicVowelLengthPattern(word): """returns a list of booleans representing which syllables have rhythmic length """ rhythmicLength = [] syl = Syllables.getSyllables(word) cvCount = 0 for s in syl: if Syllables.syllableMatches(s, 'CV'): cvCount += 1 if cvCount % 2 == 0: #FIXME should not be true if cvCount = 0 because of the cvCount +=1 line, but need to test just to make sure. 0 should return false rhythmicLength.append(True) else: rhythmicLength.append(False) else: cvCount = 0 rhythmicLength.append(False) # probably not best this way, but last syllable doesn't receive rhythmic Length ever. rhythmicLength[-1] = False return rhythmicLength
def getStressPattern(word): stressPat = [] syl = Syllables.getSyllables(word) rhy = getRhythmicVowelLengthPattern(word) ruleOne = False numStressed = 0 for i in range(len(syl)): if ruleOne: numStressed += 1 # first syllable is closed if i < len(syl) - 1: if i == 0 and Syllables.syllableMatches(syl[i], 'C'): stressPat.append(True) ruleOne = True numStressed = 0 # syllable is closed and previous syllable is unstress/open elif i > 0 and Syllables.syllableMatches(syl[i], 'C') and not stressPat[-1] and Syllables.syllableMatches(syl[i - 1], 'V'): stressPat.append(True) ruleOne = True numStressed = 0 # syllable contains VV elif Syllables.syllableMatches(syl[i], '[C]VV[C]'): stressPat.append(True) ruleOne = True numStressed = 0 # syllable is rhythmically lengthened elif rhy[i]: stressPat.append(True) ruleOne = True numStressed = 0 # after finding one of the above rules, every even number syllable gets stress elif ruleOne and numStressed > 0 and numStressed % 2 == 0 and Syllables.syllableMatches(syl[i], 'C'): stressPat.append(True) #syllable preceeding one containing VV #FIXME group of OR statements below is a workaround because '[]' format doesn't work correctly in syllableMatches() elif i < len(syl) - 1 and ( Syllables.syllableMatches(syl[i + 1], 'CVV') or Syllables.syllableMatches(syl[i + 1], 'VVC') or Syllables.syllableMatches( syl[i + 1], 'VV')): stressPat.append(True) else: stressPat.append(False) else: stressPat.append(False) return stressPat
def applyPostbase(word, postbase): """ add a postbase to a word """ #TODO would be cool if you could pass a list of postbases in here and have it do the "right thing" exp = Base.explode(word) keepStrongCfinal = False # @ symbol? dropVCfinal = False attachIrregular = False #keep the final consonant plus = string.find(postbase, '+') if plus > -1: postbase = postbase[:plus] + postbase[plus + 1:] # FIXME need to check against words that contain '-' as a part of the word # FIXME this might cause trouble with enclitics # remove the last consonant minus = string.find(postbase, '-') if minus > -1: postbase = postbase[:minus] + postbase[minus + 1:] if not Word.isVowel(exp[-1]): exp.pop(-1) # remove final 'e' tilde = string.find(postbase, '~') if tilde > -1: postbase = postbase[:tilde] + postbase[tilde + 1:] if exp[-1] == 'e': exp.pop(-1) # choose between letters in parenthesis paren = string.find(postbase, '(') if paren > -1: pl = parenLetter(word, postbase) #FIXME, what if multiple parens parenOpen = string.find(postbase, '(') parenClose = string.find(postbase, ')') + 1 postbase = postbase[:parenOpen] + pl + postbase[parenClose:] # add gemination if needed #FIXME not tested on words that contain 2 \' ...does such a word exist? apos = string.find(postbase, '\'') if apos > -1: postbase = postbase[:apos] + postbase[apos + 1:] # FIXME this may indicate that there's something that needs tweaked about the syllablematches # function. A short base is defined as [C]VCe, currently this only tests the end of the word. # this should match VCe and CVCe only shortA = len(exp) == 3 and Syllables.syllableMatches(exp, 'VCe') shortB = len(exp) == 4 and Syllables.syllableMatches(exp, 'CVCe') if shortA or shortB: exp.pop(-1) if Syllables.syllableCount(exp) == 1: exp.append('\'') elif exp[-1] == 'e': exp.pop(-1) # velar dropping suffixes colon = string.find(postbase, ':') if colon > -1: testsuf = exp[-1] + postbase testExp = Base.explode(testsuf) colon = testExp.index(':') velar = testExp[colon + 1] testExp = testExp[:colon] + testExp[colon + 1:] if Syllables.syllableMatches(testExp, 'CV' + velar + 'V'): #FIXME might crash if word isn't long enough testExp = Base.explode(postbase) colon = testExp.index(':') testExp.pop(colon) testExp.pop(colon) else: testExp = Base.explode(postbase) colon = testExp.index(':') testExp.pop(colon) postbase = ''.join(testExp) if postbase[0] == '÷': keepStrongCfinal = True if string.find(postbase, ':') > -1: dropVelar = True if postbase[0] == '- -': dropVCfinal = True if postbase[0] == '%': attachIrregular = True word = ''.join(exp) word = word + postbase #cleanup for words that wind up not needing the \' for gemination because they are followed by 2 vowels #FIXME not tested on words that contain 2 \' ...does such a word exist exp = Base.explode(word) try: gemmarker = exp.index('\'') except ValueError: gemmarker = -1 if gemmarker > -1 and len(exp) >= gemmarker + 3: syl = exp[gemmarker + 1:gemmarker + 3] if Syllables.syllableMatches(syl, 'VV'): exp.pop(gemmarker) word = ''.join(exp) return word
def applyPostbase(word, postbase): """ add a postbase to a word """ #TODO would be cool if you could pass a list of postbases in here and have it do the "right thing" exp = Base.explode(word) keepStrongCfinal = False # @ symbol? dropVCfinal = False attachIrregular = False #keep the final consonant plus = string.find(postbase, '+') if plus > -1: postbase = postbase[:plus] + postbase[plus + 1:] # FIXME need to check against words that contain '-' as a part of the word # FIXME this might cause trouble with enclitics # remove the last consonant minus = string.find(postbase, '-') if minus > -1: postbase = postbase[:minus] + postbase[minus + 1:] if not Word.isVowel(exp[-1]): exp.pop(-1) # remove final 'e' tilde = string.find(postbase, '~') if tilde > -1: postbase = postbase[:tilde] + postbase[tilde + 1:] if exp[-1] == 'e': exp.pop(-1) # choose between letters in parenthesis paren = string.find(postbase, '(') if paren > -1: pl = parenLetter(word, postbase) #FIXME, what if multiple parens parenOpen = string.find(postbase, '(') parenClose = string.find(postbase, ')') + 1 postbase = postbase[:parenOpen] + pl + postbase[parenClose:] # add gemination if needed #FIXME not tested on words that contain 2 \' ...does such a word exist? apos = string.find(postbase, '\'') if apos > -1: postbase = postbase[:apos] + postbase[apos + 1:] # FIXME this may indicate that there's something that needs tweaked about the syllablematches # function. A short base is defined as [C]VCe, currently this only tests the end of the word. # this should match VCe and CVCe only shortA = len(exp) == 3 and Syllables.syllableMatches(exp, 'VCe') shortB = len(exp) == 4 and Syllables.syllableMatches(exp, 'CVCe') if shortA or shortB: exp.pop(-1) if Syllables.syllableCount(exp) == 1: exp.append('\'') elif exp[-1] == 'e': exp.pop(-1) # velar dropping suffixes colon = string.find(postbase, ':') if colon > -1: testsuf = exp[-1] + postbase testExp = Base.explode(testsuf) colon = testExp.index(':') velar = testExp[colon + 1] testExp = testExp[:colon] + testExp[colon + 1:] if Syllables.syllableMatches( testExp, 'CV' + velar + 'V'): #FIXME might crash if word isn't long enough testExp = Base.explode(postbase) colon = testExp.index(':') testExp.pop(colon) testExp.pop(colon) else: testExp = Base.explode(postbase) colon = testExp.index(':') testExp.pop(colon) postbase = ''.join(testExp) if postbase[0] == '÷': keepStrongCfinal = True if string.find(postbase, ':') > -1: dropVelar = True if postbase[0] == '- -': dropVCfinal = True if postbase[0] == '%': attachIrregular = True word = ''.join(exp) word = word + postbase #cleanup for words that wind up not needing the \' for gemination because they are followed by 2 vowels #FIXME not tested on words that contain 2 \' ...does such a word exist exp = Base.explode(word) try: gemmarker = exp.index('\'') except ValueError: gemmarker = -1 if gemmarker > -1 and len(exp) >= gemmarker + 3: syl = exp[gemmarker + 1:gemmarker + 3] if Syllables.syllableMatches(syl, 'VV'): exp.pop(gemmarker) word = ''.join(exp) return word
def isClassIV(base): """ words that end in 'te' """ exp = explode(base) isClass = len(exp) > 1 and Syllables.syllableMatches(exp, 'te') return isClass