cvc(i) is true <=> i-2,i-1,i has the form consonant - vowel - consonant
and also if the second c is not w,x or y. this is used when trying to
restore an e at the end of a short word. e.g.
cav(e), lov(e), hop(e), crim(e), but snow, box, tray.
765582
private final boolean cvc(int i) {
        if (i < 2 || !isConsonant(i) || isConsonant(i - 1) || !isConsonant(i - 2)) {
            return false;
        }
        {
            int ch = b[i];
            if (ch == 'w' || ch == 'x' || ch == 'y') {
                return false;
            }
        }
        return true;
    }
1002168
def stem(self, word):
        
        word = word.lower()

        step1_success = False
        rv_ending_found = False
        step2a_success = False
        step2b_success = False

        # Every occurrence of 'u' after 'q' is put into upper case.
        for i in range(1, len(word)):
            if word[i-1] == "q" and word[i] == "u":
                word = "".join((word[:i], "U", word[i+1:]))

        # Every occurrence of 'u' and 'i'
        # between vowels is put into upper case.
        # Every occurrence of 'y' preceded or
        # followed by a vowel is also put into upper case.
        for i in range(1, len(word)-1):
            if word[i-1] in self.__vowels and word[i+1] in self.__vowels:
                if word[i] == "u":
                    word = "".join((word[:i], "U", word[i+1:]))

                elif word[i] == "i":
                    word = "".join((word[:i], "I", word[i+1:]))

            if word[i-1] in self.__vowels or word[i+1] in self.__vowels:
                if word[i] == "y":
                    word = "".join((word[:i], "Y", word[i+1:]))

        r1, r2 = self._r1r2_standard(word, self.__vowels)
        rv = self.__rv_french(word, self.__vowels)

        # STEP 1: Standard suffix removal
        for suffix in self.__step1_suffixes:
            if word.endswith(suffix):
                if suffix == "eaux":
                    word = word[:-1]
                    step1_success = True

                elif suffix in ("euse", "euses"):
                    if suffix in r2:
                        word = word[:-len(suffix)]
                        step1_success = True

                    elif suffix in r1:
                        word = "".join((word[:-len(suffix)], "eux"))
                        step1_success = True

                elif suffix in ("ement", "ements") and suffix in rv:
                    word = word[:-len(suffix)]
                    step1_success = True

                    if word[-2:] == "iv" and "iv" in r2:
                        word = word[:-2]

                        if word[-2:] == "at" and "at" in r2:
                            word = word[:-2]

                    elif word[-3:] == "eus":
                        if "eus" in r2:
                            word = word[:-3]
                        elif "eus" in r1:
                            word = "".join((word[:-1], "x"))

                    elif word[-3:] in ("abl", "iqU"):
                        if "abl" in r2 or "iqU" in r2:
                            word = word[:-3]

                    elif word[-3:] in ("i\xE8r", "I\xE8r"):
                        if "i\xE8r" in rv or "I\xE8r" in rv:
                            word = "".join((word[:-3], "i"))

                elif suffix == "amment" and suffix in rv:
                    word = "".join((word[:-6], "ant"))
                    rv = "".join((rv[:-6], "ant"))
                    rv_ending_found = True

                elif suffix == "emment" and suffix in rv:
                    word = "".join((word[:-6], "ent"))
                    rv_ending_found = True

                elif (suffix in ("ment", "ments") and suffix in rv and
                      not rv.startswith(suffix) and
                      rv[rv.rindex(suffix)-1] in self.__vowels):
                    word = word[:-len(suffix)]
                    rv = rv[:-len(suffix)]
                    rv_ending_found = True

                elif suffix == "aux" and suffix in r1:
                    word = "".join((word[:-2], "l"))
                    step1_success = True

                elif (suffix in ("issement", "issements") and suffix in r1
                      and word[-len(suffix)-1] not in self.__vowels):
                    word = word[:-len(suffix)]
                    step1_success = True

                elif suffix in ("ance", "iqUe", "isme", "able", "iste",
                              "eux", "ances", "iqUes", "ismes",
                              "ables", "istes") and suffix in r2:
                    word = word[:-len(suffix)]
                    step1_success = True

                elif suffix in ("atrice", "ateur", "ation", "atrices",
                                "ateurs", "ations") and suffix in r2:
                    word = word[:-len(suffix)]
                    step1_success = True

                    if word[-2:] == "ic":
                        if "ic" in r2:
                            word = word[:-2]
                        else:
                            word = "".join((word[:-2], "iqU"))

                elif suffix in ("logie", "logies") and suffix in r2:
                    word = "".join((word[:-len(suffix)], "log"))
                    step1_success = True

                elif (suffix in ("usion", "ution", "usions", "utions") and
                      suffix in r2):
                    word = "".join((word[:-len(suffix)], "u"))
                    step1_success = True

                elif suffix in ("ence", "ences") and suffix in r2:
                    word = "".join((word[:-len(suffix)], "ent"))
                    step1_success = True

                elif suffix in ("it\xE9", "it\xE9s") and suffix in r2:
                    word = word[:-len(suffix)]
                    step1_success = True

                    if word[-4:] == "abil":
                        if "abil" in r2:
                            word = word[:-4]
                        else:
                            word = "".join((word[:-2], "l"))

                    elif word[-2:] == "ic":
                        if "ic" in r2:
                            word = word[:-2]
                        else:
                            word = "".join((word[:-2], "iqU"))

                    elif word[-2:] == "iv":
                        if "iv" in r2:
                            word = word[:-2]

                elif (suffix in ("if", "ive", "ifs", "ives") and
                      suffix in r2):
                    word = word[:-len(suffix)]
                    step1_success = True

                    if word[-2:] == "at" and "at" in r2:
                        word = word[:-2]

                        if word[-2:] == "ic":
                            if "ic" in r2:
                                word = word[:-2]
                            else:
                                word = "".join((word[:-2], "iqU"))
                break

        # STEP 2a: Verb suffixes beginning 'i'
        if not step1_success or rv_ending_found:
            for suffix in self.__step2a_suffixes:
                if word.endswith(suffix):
                    if (suffix in rv and len(rv) > len(suffix) and
                        rv[rv.rindex(suffix)-1] not in self.__vowels):
                        word = word[:-len(suffix)]
                        step2a_success = True
                    break

        # STEP 2b: Other verb suffixes
            if not step2a_success:
                for suffix in self.__step2b_suffixes:
                    if rv.endswith(suffix):
                        if suffix == "ions" and "ions" in r2:
                            word = word[:-4]
                            step2b_success = True

                        elif suffix in ('eraIent', 'erions', '\xE8rent',
                                        'erais', 'erait', 'eriez',
                                        'erons', 'eront', 'erai', 'eras',
                                        'erez', '\xE9es', 'era', 'iez',
                                        '\xE9e', '\xE9s', 'er', 'ez',
                                        '\xE9'):
                            word = word[:-len(suffix)]
                            step2b_success = True

                        elif suffix in ('assions', 'assent', 'assiez',
                                        'aIent', 'antes', 'asses',
                                        '\xE2mes', '\xE2tes', 'ante',
                                        'ants', 'asse', 'ais', 'ait',
                                        'ant', '\xE2t', 'ai', 'as',
                                        'a'):
                            word = word[:-len(suffix)]
                            rv = rv[:-len(suffix)]
                            step2b_success = True
                            if rv.endswith("e"):
                                word = word[:-1]
                        break

        # STEP 3
        if step1_success or step2a_success or step2b_success:
            if word[-1] == "Y":
                word = "".join((word[:-1], "i"))
            elif word[-1] == "\xE7":
                word = "".join((word[:-1], "c"))

        # STEP 4: Residual suffixes
        else:
            if (len(word) >= 2 and word[-1] == "s" and
                word[-2] not in "aiou\xE8s"):
                word = word[:-1]

            for suffix in self.__step4_suffixes:
                if word.endswith(suffix):
                    if suffix in rv:
                        if (suffix == "ion" and suffix in r2 and
                            rv[-4] in "st"):
                            word = word[:-3]

                        elif suffix in ("ier", "i\xE8re", "Ier",
                                        "I\xE8re"):
                            word = "".join((word[:-len(suffix)], "i"))

                        elif suffix == "e":
                            word = word[:-1]

                        elif suffix == "\xEB" and word[-3:-1] == "gu":
                            word = word[:-1]
                        break

        # STEP 5: Undouble
        if word.endswith(("enn", "onn", "ett", "ell", "eill")):
            word = word[:-1]

        # STEP 6: Un-accent
        for i in range(1, len(word)):
            if word[-i] not in self.__vowels:
                i += 1
            else:
                if i != 1 and word[-i] in ("\xE9", "\xE8"):
                    word = "".join((word[:-i], "e", word[-i+1:]))
                break

        word = (word.replace("I", "i")
                    .replace("U", "u")
                    .replace("Y", "y"))


        return word
998381
def apply_T2(word):
    ''''''
    WORD = word
    offset = 0

    for vv in vv_sequences(WORD):
        seq = vv.group(2)

        if not is_diphthong(seq) and not is_long(seq):
            i = vv.start(2) + 1 + offset
            WORD = WORD[:i] + '.' + WORD[i:]
            offset += 1

    RULE = ' T2' if word != WORD else ''

    return WORD, RULE
1071803
private final boolean vowelinstem() {
        int i;
        for (i = 0; i <= j; i++) {
            if (!isConsonant(i)) {
                return true;
            }
        }
        return false;
    }
544740
private int _countConsecutiveChars (final char ch)
  {
    int nCount = 0;
    for (int i = 0; i < m_sValue.length (); i++)
    {
      final char c = m_sValue.charAt (i);
      if (c != ' ')
      {
        if (c != ch)
          return 0;
        nCount++;
      }
    }
    return nCount;
  }
1200416
def get_bound_form(self, noun, gender):
        """"""
        syllables = self.syllabifier.syllabify(noun)
        stem = self.stemmer.get_stem(noun, gender)
        cv_pattern = self.cv_patterner.get_cv_pattern(stem)
        # Based on Huehnergard Appendix 6.C.1: base in -VC
        if [letter[0] for letter in cv_pattern[-2:]] == ['V', 'C'] or stem in ['nakr']:
            # a. 2-syllable
            if len(syllables) > 2:
                # awīlum > awīl, nakrum > naker
                if stem in ['nakr']:
                    return 'naker'
                else:
                    return stem
            # b. 1-syllable
            elif len(syllables) > 1:
                # bēlum > bēl
                return stem
            # c. abum, aḫum
            if stem in ['ab', 'aḫ']:
                return stem + 'i'
        # Appendix 6.C.2: base in -C₁C₁
        if cv_pattern[-1][:2] == cv_pattern[-2][:2]:
            # a. 1-syllable
            if 3 > len(syllables) > 1:
                return stem + 'i'
            # b. 2-syllable, -tt
            if len(syllables) > 2 and cv_pattern[-1][2] + cv_pattern[-2][2] == 'tt':
                return stem + 'i'
            # c. 2-syllable, other
            if len(syllables) > 2:
                return stem[:-1]
        # Appendix 6.C.3: base in -C₁C₂, C₂ ≠ t, i.e. pVrs
        if cv_pattern[-1][0] == cv_pattern[-2][0] and cv_pattern[-1][1] != cv_pattern[-2][1]:
            return stem[:-1] + stem[1] + stem[-1]
        # Appendix 6.C.4: base in -Ct (fem.)
        if cv_pattern[-1][2] == 't' and cv_pattern[-2][0] == 'C':
            if len(syllables) > 2:
                return stem + 'i'
            # Need to deal with fem. Ptcpl. māḫirtum -> māḫirat
            if len(syllables) > 1:
                # These are case by case
                if stem in ['qīšt']:
                    return stem + 'i'
                if stem in ['mārt']:
                    return stem[:-1] + stem[1] + stem[-1]
15089
def _ends_with_vowel(self, letter_group: str) -> bool:
        """"""
        if len(letter_group) == 0:
            return False
        return self._contains_vowels(letter_group[-1])
553462
def apply_T6(word):
    ''''''
    WORD = word
    offset = 0

    for vvv in vvv_sequences(WORD):
        seq = vvv.group(2)
        j = 2 if is_long(seq[:2]) else 1 if is_long(seq[1:]) else 0

        if j:
            i = vvv.start(2) + j + offset
            WORD = WORD[:i] + '.' + WORD[i:]
            offset += 1

    RULE = ' T6' if word != WORD else ''

    return WORD, RULE
1216580
private static function cvc($str)
    {
        $c = self::$regex_consonant;
        $v = self::$regex_vowel;

        return     preg_match("#($c$v$c)$#", $str, $matches)
               and strlen($matches[1]) == 3
               and $matches[1]{2} != 'w'
               and $matches[1]{2} != 'x'
               and $matches[1]{2} != 'y';
    }
755873
private final boolean cvc(int i) {
		if (i < k0 + 2 || !cons(i) || cons(i - 1) || !cons(i - 2))
			return false;
		else {
			int ch = b[i];
			if (ch == 'w' || ch == 'x' || ch == 'y')
				return false;
		}
		return true;
	}
239512
def apply_T7(word):
    ''''''
    WORD = _split_consonants_and_vowels(word)

    for k, v in WORD.iteritems():

        if len(v) == 3 and is_vowel(v[0]):
            WORD[k] = v[:2] + '.' + v[2:]

    word = _compile_dict_into_word(WORD)

    return word
1295629
def apply_T6(word):
    ''''''
    T6 = ''
    WORD = word.split('.')

    for i, v in enumerate(WORD):

        if contains_VVV(v):
            VV = [v.find(j) for j in LONG_VOWELS if v.find(j) > 0]

            if VV:
                I = VV[0]
                T6 = ' T6'

                if I + 2 == len(v) or is_vowel(v[I + 2]):
                    WORD[i] = v[:I + 2] + '.' + v[I + 2:]  # TODO

                else:
                    WORD[i] = v[:I] + '.' + v[I:]

    word = '.'.join(WORD)
    word = word.strip('.')  # TODO

    return word, T6
115754
def _char_ro_vowel(self, char_info, type):
        '''
        
        '''
        if type == CV:
            return char_info[3]

        if type == VOWEL or type == XVOWEL:
            return char_info[0]

        return None
747568
def get_cv_pattern(self, word, pprint=False):
        
        subscripts = {
            1: '₁',
            2: '₂',
            3: '₃',
            4: '₄',
            5: '₅',
            6: '₆',
            7: '₇',
            8: '₈',
            9: '₉',
            0: '₀'
        }
        pattern = []
        c_count = 1
        v_count = 1
        count = 0
        for char in word:
            if char in self.akkadian['consonants']:
                cv = 'C'
            else:
                cv = 'V'
                # remove length:
                if char in self.akkadian['macron_vowels']:
                    char = self.akkadian['short_vowels'][self.akkadian['macron_vowels'].index(char)]
                elif char in self.akkadian['circumflex_vowels']:
                    char = self.akkadian['short_vowels'][self.akkadian['circumflex_vowels'].index(char)]
            if char not in [x[2] for x in pattern]:
                if cv == 'C':
                    count = c_count
                    c_count += 1
                elif cv == 'V':
                    count = v_count
                    v_count += 1
                pattern.append((cv, count, char))
            elif char in [x[2] for x in pattern]:
                pattern.append((cv, next(x[1] for x in pattern if x[2] == char), char))
        if pprint:
            output = ''
            for item in pattern:
                output += (item[0] + subscripts[item[1]])
            return output
        return pattern
858695
protected function cvc($i)
    {
        if ($i < 2 || !$this->cons($i) || $this->cons($i-1) || !$this->cons($i-2))
            return false;
        $ch = $this->b[$i];
        if ($ch === 'w' || $ch === 'x' || $ch === 'y')
            return false;

        return true;
    }
432472
def stem_helper(word, rem_umlaut = True):
	""""""
	
	#Define R1 and R2 regions
	
	#R1 is defined as the region after the first consonant followed by a vowel
	
	try:
		R1 = list(re.finditer(r"[aëeiouäöüâêîôûæœ][bdghfcjklmnspqrtvwz]",word))[0].start() + 2
	except:
		R1 = len(word)
		
	#R2 is defined as the region within R1 after the first consonant followed by a vowel
	
	try:
		R2 = list(re.finditer(r"[aëeiouäöüâêîôûæœ][bdghfcjklmnspqrtvwz]",word[R1:]))[0].start() + 2 + R1
	except:
		R2 = len(word)
		
	#Make sure the index of R1 is at least 3. 
	
	if R1<3:
		try:
			R1 = list(re.finditer(r"[aëeiouäöüâêîôûæœ][bdghfcjklmnspqrtvwz]",word[1:]))[0].start() + 2
		except:
			R1 = len(word)
	
	if rem_umlaut:
		word = remove_umlaut(word)
	
	word = word[:R1] + re.sub(r'(wes|wen|est|ern|em|en|er|es|eȥ(?=[klmrt])s|(?=[lr])n|e)$',"",word[R1:])
	word = word[:R1] + re.sub(r'(est|er|en|re|in|iu|(?=.{3})st,word[R1:])$',"",word[R1:])
	word = word[:R2] + re.sub(r'(lich?.?.|keit|inc|isch?.?.)$',"",word[R2:])
	
	return word
138592
def stem(self, word):
        
        word = word.lower()

        step2_success = False

        # Vowel accents are removed.
        word = (word.replace("\xE4", "a").replace("\xE1", "a")
                    .replace("\xEB", "e").replace("\xE9", "e")
                    .replace("\xED", "i").replace("\xEF", "i")
                    .replace("\xF6", "o").replace("\xF3", "o")
                    .replace("\xFC", "u").replace("\xFA", "u"))

        # An initial 'y', a 'y' after a vowel,
        # and an 'i' between self.__vowels is put into upper case.
        # As from now these are treated as consonants.
        if word.startswith("y"):
            word = "".join(("Y", word[1:]))

        for i in range(1, len(word)):
            if word[i-1] in self.__vowels and word[i] == "y":
                word = "".join((word[:i], "Y", word[i+1:]))

        for i in range(1, len(word)-1):
            if (word[i-1] in self.__vowels and word[i] == "i" and
               word[i+1] in self.__vowels):
                word = "".join((word[:i], "I", word[i+1:]))

        r1, r2 = self._r1r2_standard(word, self.__vowels)

        # R1 is adjusted so that the region before it
        # contains at least 3 letters.
        for i in range(1, len(word)):
            if word[i] not in self.__vowels and word[i-1] in self.__vowels:
                if len(word[:i+1]) < 3 and len(word[:i+1]) > 0:
                    r1 = word[3:]
                elif len(word[:i+1]) == 0:
                    return word
                break

        # STEP 1
        for suffix in self.__step1_suffixes:
            if r1.endswith(suffix):
                if suffix == "heden":
                    word = "".join((word[:-5], "heid"))
                    r1 = "".join((r1[:-5], "heid"))
                    if r2.endswith("heden"):
                        r2 = "".join((r2[:-5], "heid"))

                elif (suffix in ("ene", "en") and
                      not word.endswith("heden") and
                      word[-len(suffix)-1] not in self.__vowels and
                      word[-len(suffix)-3:-len(suffix)] != "gem"):
                    word = word[:-len(suffix)]
                    r1 = r1[:-len(suffix)]
                    r2 = r2[:-len(suffix)]
                    if word.endswith(("kk", "dd", "tt")):
                        word = word[:-1]
                        r1 = r1[:-1]
                        r2 = r2[:-1]

                elif (suffix in ("se", "s") and
                      word[-len(suffix)-1] not in self.__vowels and
                      word[-len(suffix)-1] != "j"):
                    word = word[:-len(suffix)]
                    r1 = r1[:-len(suffix)]
                    r2 = r2[:-len(suffix)]
                break

        # STEP 2
        if r1.endswith("e") and word[-2] not in self.__vowels:
            step2_success = True
            word = word[:-1]
            r1 = r1[:-1]
            r2 = r2[:-1]

            if word.endswith(("kk", "dd", "tt")):
                word = word[:-1]
                r1 = r1[:-1]
                r2 = r2[:-1]

        # STEP 3a
        if r2.endswith("heid") and word[-5] != "c":
            word = word[:-4]
            r1 = r1[:-4]
            r2 = r2[:-4]

            if (r1.endswith("en") and word[-3] not in self.__vowels and
                word[-5:-2] != "gem"):
                word = word[:-2]
                r1 = r1[:-2]
                r2 = r2[:-2]

                if word.endswith(("kk", "dd", "tt")):
                    word = word[:-1]
                    r1 = r1[:-1]
                    r2 = r2[:-1]

        # STEP 3b: Derivational suffixes
        for suffix in self.__step3b_suffixes:
            if r2.endswith(suffix):
                if suffix in ("end", "ing"):
                    word = word[:-3]
                    r2 = r2[:-3]

                    if r2.endswith("ig") and word[-3] != "e":
                        word = word[:-2]
                    else:
                        if word.endswith(("kk", "dd", "tt")):
                            word = word[:-1]

                elif suffix == "ig" and word[-3] != "e":
                    word = word[:-2]

                elif suffix == "lijk":
                    word = word[:-4]
                    r1 = r1[:-4]

                    if r1.endswith("e") and word[-2] not in self.__vowels:
                        word = word[:-1]
                        if word.endswith(("kk", "dd", "tt")):
                            word = word[:-1]

                elif suffix == "baar":
                    word = word[:-4]

                elif suffix == "bar" and step2_success:
                    word = word[:-3]
                break

        # STEP 4: Undouble vowel
        if len(word) >= 4:
            if word[-1] not in self.__vowels and word[-1] != "I":
                if word[-3:-1] in ("aa", "ee", "oo", "uu"):
                    if word[-4] not in self.__vowels:
                        word = "".join((word[:-3], word[-3], word[-1]))

        # All occurrences of 'I' and 'Y' are put back into lower case.
        word = word.replace("I", "i").replace("Y", "y")


        return word