From 759d901b57afb6163957fafd7ec3857fb712369e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Tue, 16 Mar 2021 11:09:46 +0100 Subject: [PATCH] Base project --- .vscode/launch.json | 27 ++ .vscode/tasks.json | 42 ++++ LanguageGenerator/LanguageGenerator.csproj | 8 + LanguageGenerator/Program.cs | 276 +++++++++++++++++++++ LanguageGenerator/append.xml | 6 + 5 files changed, 359 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 LanguageGenerator/LanguageGenerator.csproj create mode 100644 LanguageGenerator/Program.cs create mode 100644 LanguageGenerator/append.xml diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a5da09a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/LanguageGenerator/bin/Debug/net5.0/LanguageGenerator.dll", + "args": [], + "cwd": "${workspaceFolder}/LanguageGenerator", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..f8a6c20 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/LanguageGenerator/LanguageGenerator.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/LanguageGenerator/LanguageGenerator.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "${workspaceFolder}/LanguageGenerator/LanguageGenerator.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/LanguageGenerator/LanguageGenerator.csproj b/LanguageGenerator/LanguageGenerator.csproj new file mode 100644 index 0000000..2082704 --- /dev/null +++ b/LanguageGenerator/LanguageGenerator.csproj @@ -0,0 +1,8 @@ + + + + Exe + net5.0 + + + diff --git a/LanguageGenerator/Program.cs b/LanguageGenerator/Program.cs new file mode 100644 index 0000000..5d2f360 --- /dev/null +++ b/LanguageGenerator/Program.cs @@ -0,0 +1,276 @@ +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', 's', 'i', 'n', 'e', 'l', 'a', 't'}, + {'g', 'b', 'm', 'o', 'z', 'r', 'y', 'v'}, + {'x', 'p', 'f', 'd', 'j', 'c', 'u', 'h'}, + {'q', '?', '!', 'w', '@', ',', '.', '\''} + }; + private static readonly char[,] capitalCharacters = new char[4, 8] + { + {'K', 'S', 'I', 'N', 'E', 'L', 'A', 'T'}, + {'G', 'B', 'M', 'O', 'Z', 'R', 'Y', 'V'}, + {'X', 'P', 'F', 'D', 'J', 'C', 'U', 'H'}, + {'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 + ""); + } + + 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 when c == '?' => new KeyboardAction(new StringContent("?"), movementActions), + var c when c == '!' => new KeyboardAction(new StringContent("!"), movementActions), + var c when c == '@' => new KeyboardAction(new StringContent("@"), movementActions), + var c when c == ',' => new KeyboardAction(new StringContent(","), movementActions), + var c when c == '.' => new KeyboardAction(new StringContent("."), movementActions), + var c when c == '\'' => new KeyboardAction(new StringContent("\'"), movementActions), + var c when c == '-' => new KeyboardAction(new StringContent("?"), movementActions), + var c when c == '_' => new KeyboardAction(new StringContent("!"), movementActions), + var c when c == '*' => new KeyboardAction(new StringContent("@"), movementActions), + var c when c == '/' => new KeyboardAction(new StringContent(","), movementActions), + var c when c == ':' => new KeyboardAction(new StringContent("."), movementActions), + var c when c == '\"' => new KeyboardAction(new StringContent("\'"), movementActions), */ + var c => new KeyboardAction(new StringContent(c.ToString()), movementActions) + //_ => throw new ArgumentException($"Unknown character: '{chr}' ({(int)chr})") + }; + } + + 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"; + } +} diff --git a/LanguageGenerator/append.xml b/LanguageGenerator/append.xml new file mode 100644 index 0000000..900828d --- /dev/null +++ b/LanguageGenerator/append.xml @@ -0,0 +1,6 @@ + + + INPUT_TEXT + INSIDE_CIRCLE;BOTTOM;LEFT;TOP;RIGHT;BOTTOM;LEFT;TOP;RIGHT;BOTTOM;INSIDE_CIRCLE; + kovacsadam07@outlook.hu + \ No newline at end of file