private void Compact(CharVector kx, TernaryTree map, char p) { int k; if (p == 0) { return; } if (m_sc[p] == 0xFFFF) { k = map.Find(m_kv.Array, m_lo[p]); if (k < 0) { k = kx.Alloc(StrLen(m_kv.Array, m_lo[p]) + 1); StrCpy(kx.Array, k, m_kv.Array, m_lo[p]); map.Insert(kx.Array, k, (char)k); } m_lo[p] = (char)k; } else { Compact(kx, map, m_lo[p]); if (m_sc[p] != 0) { Compact(kx, map, m_eq[p]); } Compact(kx, map, m_hi[p]); } }
/// <summary> /// Add a pattern to the tree. Mainly, to be used by /// <see cref="PatternParser"/> class as callback to add a pattern to /// the tree. /// </summary> /// <param name="pattern"> the hyphenation pattern </param> /// <param name="ivalue"> interletter weight values indicating the desirability and /// priority of hyphenating at a given point within the pattern. It /// should contain only digit characters. (i.e. '0' to '9'). </param> public virtual void AddPattern(string pattern, string ivalue) { int k = ivalues.Find(ivalue); if (k <= 0) { k = PackValues(ivalue); ivalues.Insert(ivalue, (char)k); } Insert(pattern, (char)k); }
/// <summary> /// Hyphenate word and return an array of hyphenation points. /// </summary> /// <remarks> /// w = "****nnllllllnnn*****", where n is a non-letter, l is a letter, all n /// may be absent, the first n is at offset, the first l is at offset + /// iIgnoreAtBeginning; word = ".llllll.'\0'***", where all l in w are copied /// into word. In the first part of the routine len = w.length, in the second /// part of the routine len = word.length. Three indices are used: index(w), /// the index in w, index(word), the index in word, letterindex(word), the /// index in the letter part of word. The following relations exist: index(w) = /// offset + i - 1 index(word) = i - iIgnoreAtBeginning letterindex(word) = /// index(word) - 1 (see first loop). It follows that: index(w) - index(word) = /// offset - 1 + iIgnoreAtBeginning index(w) = letterindex(word) + offset + /// iIgnoreAtBeginning /// </remarks> /// <param name="w"> char array that contains the word </param> /// <param name="offset"> Offset to first character in word </param> /// <param name="len"> Length of word </param> /// <param name="remainCharCount"> Minimum number of characters allowed before the /// hyphenation point. </param> /// <param name="pushCharCount"> Minimum number of characters allowed after the /// hyphenation point. </param> /// <returns> a <see cref="Hyphenation"/> object representing the /// hyphenated word or null if word is not hyphenated. </returns> public virtual Hyphenation Hyphenate(char[] w, int offset, int len, int remainCharCount, int pushCharCount) { int i; char[] word = new char[len + 3]; // normalize word char[] c = new char[2]; int iIgnoreAtBeginning = 0; int iLength = len; bool bEndOfLetters = false; for (i = 1; i <= len; i++) { c[0] = w[offset + i - 1]; int nc = m_classmap.Find(c, 0); if (nc < 0) // found a non-letter character ... { if (i == (1 + iIgnoreAtBeginning)) { // ... before any letter character iIgnoreAtBeginning++; } else { // ... after a letter character bEndOfLetters = true; } iLength--; } else { if (!bEndOfLetters) { word[i - iIgnoreAtBeginning] = (char)nc; } else { return(null); } } } len = iLength; if (len < (remainCharCount + pushCharCount)) { // word is too short to be hyphenated return(null); } int[] result = new int[len + 1]; int k = 0; // check exception list first string sw = new string(word, 1, len); if (m_stoplist.ContainsKey(sw)) { // assume only simple hyphens (Hyphen.pre="-", Hyphen.post = Hyphen.no = // null) IList <object> hw = m_stoplist[sw]; int j = 0; for (i = 0; i < hw.Count; i++) { object o = hw[i]; // j = index(sw) = letterindex(word)? // result[k] = corresponding index(w) if (o is string) { j += ((string)o).Length; if (j >= remainCharCount && j < (len - pushCharCount)) { result[k++] = j + iIgnoreAtBeginning; } } } } else { // use algorithm to get hyphenation points word[0] = '.'; // word start marker word[len + 1] = '.'; // word end marker word[len + 2] = (char)0; // null terminated byte[] il = new byte[len + 3]; // initialized to zero for (i = 0; i < len + 1; i++) { SearchPatterns(word, i, il); } // hyphenation points are located where interletter value is odd // i is letterindex(word), // i + 1 is index(word), // result[k] = corresponding index(w) for (i = 0; i < len; i++) { if (((il[i + 1] & 1) == 1) && i >= remainCharCount && i <= (len - pushCharCount)) { result[k++] = i + iIgnoreAtBeginning; } } } if (k > 0) { // trim result array int[] res = new int[k + 2]; Array.Copy(result, 0, res, 1, k); // We add the synthetical hyphenation points // at the beginning and end of the word res[0] = 0; res[k + 1] = len; return(new Hyphenation(res)); } else { return(null); } }