/// <summary> /// 오토마타 스코프 글자에서 만약 <paramref name="castChar"/>이 모음이거나 이중 자음이지만, /// <para>한 글자에 있는 것이 불가능한 경우, 마지막 문자를 가져와 다음 오토마타를 만들어 붙이고 탈출합니다.</para> /// </summary> /// <param name="castChar">다음 오토마타에 붙일 새 문자</param> private static void EscapeGlyph(char castChar) { //if (characterHistory.Count <= 2) return; if (Vowel.ContainsKey(castChar)) { char lastIndex = characterHistory[characterHistory.Count - 1]; if (UndoAutomata()) { GlyphInfo data = Consonant[characterHistory[characterHistory.Count - 1]]; lastIndex = data.constructGlyphs[(int)Consonant[lastIndex].index - (int)data.index - 1]; } EscapeGlyph(); characterHistory.Add(lastIndex); scopeHistory.Add(currentScope = AutomataScope.first); } else { EscapeGlyph(); scopeHistory.Add(currentScope = AutomataScope.idle); } PushAutomata(castChar); }
/// <summary> /// 오토마타로 만들어지는 글리프를 되돌리거나 텍스트에서 문자를 제거합니다. /// </summary> public static bool UndoAutomata() { buildResult = UNDERBAR_IDLE; if (characterHistory.Count > 0) { if (Consonant.ContainsKey(characterHistory[characterHistory.Count - 1])) { uint glyph = characterHistory[characterHistory.Count - 1]; GlyphInfo data = Consonant[Convert.ToChar(glyph)]; if (data.constructGlyphs == null && data.endUpStyle != EndUpStyle.alone) { while (data.constructGlyphs == null) { data = Consonant[Convert.ToChar(--glyph)]; } characterHistory[characterHistory.Count - 1] = Convert.ToChar(glyph); buildResult = BuildGlyph(characterHistory); return(true); } } else if (Vowel.ContainsKey(characterHistory[characterHistory.Count - 1])) { uint glyph = characterHistory[characterHistory.Count - 1]; GlyphInfo data = Vowel[Convert.ToChar(glyph)]; if (data.constructGlyphs == null) { while (data.constructGlyphs == null || (data.constructGlyphs != null && data.constructGlyphs.Length <= 1)) { data = Vowel[Convert.ToChar(--glyph)]; } characterHistory[characterHistory.Count - 1] = Convert.ToChar(glyph); buildResult = BuildGlyph(characterHistory); return(true); } } characterHistory.RemoveAt(characterHistory.Count - 1); scopeHistory.RemoveAt(scopeHistory.Count - 1); currentScope = scopeHistory.Count > 0 ? scopeHistory[scopeHistory.Count - 1] : AutomataScope.idle; buildResult = BuildGlyph(characterHistory); } else if (currentText.Length > 1) { currentText = currentText.Remove(currentText.Length - 1); } else { currentText = ""; } return(false); }
/// <summary> /// 오토마타 스코프에 잡힌 문자에서 탈출합니다. /// </summary> public static void EscapeGlyph() { char build = BuildGlyph(characterHistory); if (build != '\0') { currentText += build; } characterHistory.Clear(); scopeHistory.Clear(); scopeHistory.Add(currentScope = AutomataScope.idle); buildResult = UNDERBAR_IDLE; }
/// <summary> /// 자음 또는 모음인 글자를 오토마타에 적용합니다. /// </summary> /// <param name="glyph">자음 또는 모음인 글자</param> /// <exception cref="Exception">글자가 자음/모음이 아닌 문자</exception> public static void PushAutomata(char glyph) { if (glyph == ' ' || glyph == '_' || glyph == '_') { if (characterHistory.Count != 0) { EscapeGlyph(); } else { currentText += " "; } return; } uint scope = Convert.ToUInt32(glyph); if (scope < 0x3131 || scope > 0x3163) { throw new Exception("악"); } scope -= 0x3131; uint cacheGlyph; switch (currentScope) { default: case AutomataScope.idle: if (Consonant.ContainsKey(glyph)) { characterHistory.Clear(); scopeHistory.Clear(); characterHistory.Add(glyph); scopeHistory.Add(currentScope = AutomataScope.first); } break; case AutomataScope.first: if (characterHistory.Count != 1) { goto default; } if (Vowel.ContainsKey(glyph)) { characterHistory.Add(glyph); scopeHistory.Add(currentScope = AutomataScope.second); } else if (Consonant.ContainsKey(glyph)) { if (Consonant[characterHistory[0]] .constructGlyphs == null) { EscapeGlyph(glyph); } else if (Consonant[characterHistory[0]] .constructGlyphs.Contains(glyph)) { cacheGlyph = Convert.ToUInt32(characterHistory[0]) + (uint)Consonant[characterHistory[0]] .constructGlyphs.IndexOf(glyph) + 1; characterHistory[0] = Convert.ToChar(cacheGlyph); } else { EscapeGlyph(glyph); } } else { EscapeGlyph(glyph); } break; case AutomataScope.second: if (characterHistory.Count != 2) { goto default; } if (Consonant.ContainsKey(glyph)) { characterHistory.Add(glyph); scopeHistory.Add(currentScope = AutomataScope.last); } else if (Vowel.ContainsKey(glyph)) { if (Vowel[characterHistory[1]] .constructGlyphs == null) { EscapeGlyph(); } else if (Vowel[characterHistory[1]] .constructGlyphs.Contains(glyph)) { cacheGlyph = Convert.ToUInt32(characterHistory[1]) + (uint)Vowel[characterHistory[1]] .constructGlyphs.IndexOf(glyph) + 1; characterHistory[1] = Convert.ToChar(cacheGlyph); } else { EscapeGlyph(); } } else { EscapeGlyph(); } break; case AutomataScope.last: if (characterHistory.Count != 3) { goto default; } if (Vowel.ContainsKey(glyph)) { EscapeGlyph(glyph); } else if (Consonant.ContainsKey(glyph)) { if (Consonant[characterHistory[2]] .constructGlyphs == null) { EscapeGlyph(glyph); } else if (Consonant[characterHistory[2]] .constructGlyphs.Contains(glyph)) { cacheGlyph = Convert.ToUInt32(characterHistory[2]) + (uint)Consonant[characterHistory[2]] .constructGlyphs.IndexOf(glyph) + 1; if (Consonant[Convert.ToChar(cacheGlyph)].endUpStyle == EndUpStyle.endUp) { UndoAutomata(); EscapeGlyph(); characterHistory.Clear(); characterHistory.Add(Convert.ToChar(cacheGlyph)); scopeHistory.Clear(); scopeHistory.Add(currentScope = AutomataScope.first); } else { characterHistory[2] = Convert.ToChar(cacheGlyph); } } else { EscapeGlyph(glyph); } } break; } buildResult = BuildGlyph(characterHistory); }