using System.IO; using System.Text; using System; using System.Collections.Generic; using System.Linq; namespace LanguageGenerator { public enum CIRCLESECTION { Right = 0, Bottom = 1, Left = 2, Top = 3 } public static class Program { private static readonly char[,] smallCharacters = new char[4, 8] { {'k', 'l', 's', 'n', 'e', 'i', 'a', 't'}, {'b', 'r', 'm', 'y', 'g', 'v', 'o', 'z'}, {'c', 'f', 'p', 'x', 'h', 'j', 'u', 'd'}, {'q', '?', '!', 'w', '@', ',', '.', '\''} }; private static readonly char[,] capitalCharacters = new char[4, 8] { {'K', 'L', 'S', 'N', 'E', 'I', 'A', 'T'}, {'B', 'R', 'M', 'Y', 'G', 'V', 'O', 'Z'}, {'C', 'F', 'P', 'X', 'H', 'J', 'U', 'D'}, {'Q', '-', '_', 'W', '*', '/', ':', '\"'} }; private static readonly string[] upperCaseFlags = new string[] { "1" }; private const string fileName = "hu_eight_pen_original.xml"; private static readonly Dictionary diacritics = new() { { 'a', new char[] { 'á' } }, { 'e', new char[] { 'é' } }, { 'i', new char[] { 'í' } }, { 'o', new char[] { 'ó', 'ö', 'ő' } }, { 'u', new char[] { 'ú', 'ü', 'ű' } }, { 'A', new char[] { 'Á' } }, { 'E', new char[] { 'É' } }, { 'I', new char[] { 'Í' } }, { 'O', new char[] { 'Ó', 'Ö', 'Ő' } }, { 'U', new char[] { 'Ú', 'Ü', 'Ű' } }, }; public static void Main() { var keyboardActions = new List(); foreach (var (characters, extraLine) in new[] { (smallCharacters, 0), (capitalCharacters, 4) }) { for (var x = 0; x < characters.GetLength(0); x++) { for (var y = 0; y < characters.GetLength(1); y++) { keyboardActions.Add(CharToKeyboardAction(characters[x, y], x + extraLine, y)); } } } foreach (var keyboardAction in new List(keyboardActions)) { if (keyboardAction.Content is KeyCodeContent keyCodeContent && diacritics.ContainsKey(keyCodeContent.KeyCode)) { var keyCode = keyCodeContent.KeyCode; var diacriticsForChar = diacritics[keyCode]; for (var i = 0; i < diacriticsForChar.Length; i++) { var diacritic = diacriticsForChar[i]; var (baseMovementSequence, startToLeft) = PositionToMovementSequence(keyCodeContent.Circle, keyCodeContent.Line); startToLeft = !startToLeft; var movements = new List(baseMovementSequence); var currentSection = movements.Last(); for (var i2 = 0; i2 < i + 1; i2++) { var nextSection = GetNextSection(currentSection, startToLeft); movements.Add(nextSection); currentSection = nextSection; } keyboardActions.Add( new KeyboardAction( new StringContent(diacritic.ToString()), PositionToMovementSequenceEdges(movements.Select(m => CircleSectionToString(m))) ) ); } } } var generatedOutput = new StringBuilder(); foreach (var keyboardAction in keyboardActions) { var keyboardActionsString = $@" {keyboardAction.Content.GetActionType()} {string.Join(";", keyboardAction.MovementActions) + ";"} {keyboardAction.Content.GetContent()}{(keyboardAction.Flags.Count > 0 ? $"\n \n {string.Join("\n ", keyboardAction.Flags)}\n " : "")} "; generatedOutput.Append(keyboardActionsString); } using (var writer = File.CreateText(fileName)) { writer.Write("" + Environment.NewLine); writer.Write(generatedOutput); writer.Write(File.ReadAllText("append.xml")); writer.Write(Environment.NewLine + ""); } var lowerCaseBuilder = new StringBuilder(); var upperCaseBuilder = new StringBuilder(); foreach (var column in new int[] { 2, 4, 6, 0 }) { for (var i = 0; i < 4; i++) { lowerCaseBuilder.Append(smallCharacters[i, column]); lowerCaseBuilder.Append(smallCharacters[i, column + 1]); upperCaseBuilder.Append(capitalCharacters[i, column]); upperCaseBuilder.Append(capitalCharacters[i, column + 1]); } } var lowerCaseDisplay = lowerCaseBuilder.ToString(); var upperCaseDisplay = upperCaseBuilder.ToString(); Console.WriteLine(lowerCaseDisplay); Console.WriteLine(upperCaseDisplay); } private static KeyboardAction CharToKeyboardAction(char chr, int circle, int line) { var movementActions = PositionToMovementSequenceEdges(circle, line); return chr switch { var c when c >= 'a' && c <= 'z' => new KeyboardAction(new KeyCodeContent(c, circle, line), movementActions), var c when c >= 'A' && c <= 'Z' => new KeyboardAction(new KeyCodeContent(c, circle, line), movementActions, upperCaseFlags), var c => new KeyboardAction(new StringContent(c.ToString()), movementActions) }; } private static List PositionToMovementSequenceEdges(int fakeCircle, int line) { return PositionToMovementSequenceEdges( PositionToMovementSequence(fakeCircle, line) .movements .Select(m => CircleSectionToString(m)) ); } private static List PositionToMovementSequenceEdges(IEnumerable movements) { var allMovements = new List() { "INSIDE_CIRCLE" }; allMovements.AddRange(movements); allMovements.Add("INSIDE_CIRCLE"); return allMovements; } private static (List movements, bool startToLeft) PositionToMovementSequence(int fakeCircle, int line) { var movements = new List(); var (startPos, startToLeft) = line switch { var l when l == 0 => (CIRCLESECTION.Top, false), var l when l == 1 => (CIRCLESECTION.Right, true), var l when l == 2 => (CIRCLESECTION.Right, false), var l when l == 3 => (CIRCLESECTION.Bottom, true), var l when l == 4 => (CIRCLESECTION.Bottom, false), var l when l == 5 => (CIRCLESECTION.Left, true), var l when l == 6 => (CIRCLESECTION.Left, false), var l when l == 7 => (CIRCLESECTION.Top, true), _ => throw new Exception() }; movements.Add(startPos); var currentSection = startPos; for (var i = 0; i < fakeCircle + 1; i++) { var nextSection = GetNextSection(currentSection, startToLeft); movements.Add(nextSection); currentSection = nextSection; } return (movements, startToLeft); } private static CIRCLESECTION GetNextSection(CIRCLESECTION currentSection, bool toLeft) => currentSection switch { CIRCLESECTION.Top => toLeft ? CIRCLESECTION.Left : CIRCLESECTION.Right, CIRCLESECTION.Right => toLeft ? CIRCLESECTION.Top : CIRCLESECTION.Bottom, CIRCLESECTION.Bottom => toLeft ? CIRCLESECTION.Right : CIRCLESECTION.Left, CIRCLESECTION.Left => toLeft ? CIRCLESECTION.Bottom : CIRCLESECTION.Top, _ => throw new ArgumentException($"Unkown value of {nameof(CIRCLESECTION)}", nameof(currentSection)) }; private static string CircleSectionToString(CIRCLESECTION section) => section switch { CIRCLESECTION.Top => "TOP", CIRCLESECTION.Right => "RIGHT", CIRCLESECTION.Bottom => "BOTTOM", CIRCLESECTION.Left => "LEFT", _ => throw new ArgumentException($"Unkown value of {nameof(CIRCLESECTION)}", nameof(section)) }; } public class KeyboardAction { public KeyboardAction(IKeyboardContent content, IEnumerable movementActions, IEnumerable flags = null) { if (movementActions is null) throw new ArgumentNullException(nameof(movementActions)); Content = content; MovementActions.AddRange(movementActions); if (flags != null) Flags.AddRange(flags); } public IKeyboardContent Content { get; } public List Flags { get; } = new List(); public List MovementActions { get; } = new List(); } public interface IKeyboardContent { string GetContent(); string GetActionType(); } public class KeyCodeContent : IKeyboardContent { public KeyCodeContent(char keyCode, int circle, int line) { KeyCode = keyCode; KeyCodeText = "KEYCODE_" + keyCode.ToString().ToUpper(); Circle = circle; Line = line; } public string KeyCodeText { get; } public char KeyCode { get; } public int Circle { get; } public int Line { get; } public string GetContent() => $"{KeyCodeText}"; public string GetActionType() => "INPUT_KEY"; } public class StringContent : IKeyboardContent { public StringContent(string content) { Content = content; } public string Content { get; } public string GetContent() => $"{Content}"; public string GetActionType() => "INPUT_TEXT"; } }