285 lines
11 KiB
C#
285 lines
11 KiB
C#
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[] { "<flag>1</flag>" };
|
|
|
|
private const string fileName = "hu_eight_pen_original.xml";
|
|
|
|
private static readonly Dictionary<char, char[]> 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<KeyboardAction>();
|
|
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<KeyboardAction>(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<CIRCLESECTION>(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>
|
|
<keyboardActionType>{keyboardAction.Content.GetActionType()}</keyboardActionType>
|
|
<movementSequence>{string.Join(";", keyboardAction.MovementActions) + ";"}</movementSequence>
|
|
{keyboardAction.Content.GetContent()}{(keyboardAction.Flags.Count > 0 ? $"\n <flags>\n {string.Join("\n ", keyboardAction.Flags)}\n </flags>" : "")}
|
|
</keyboardAction>
|
|
";
|
|
|
|
generatedOutput.Append(keyboardActionsString);
|
|
}
|
|
|
|
using (var writer = File.CreateText(fileName))
|
|
{
|
|
writer.Write("<keyboardActionMap>" + Environment.NewLine);
|
|
writer.Write(generatedOutput);
|
|
writer.Write(File.ReadAllText("append.xml"));
|
|
writer.Write(Environment.NewLine + "</keyboardActionMap>");
|
|
}
|
|
|
|
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<string> PositionToMovementSequenceEdges(int fakeCircle, int line)
|
|
{
|
|
return PositionToMovementSequenceEdges(
|
|
PositionToMovementSequence(fakeCircle, line)
|
|
.movements
|
|
.Select(m => CircleSectionToString(m))
|
|
);
|
|
}
|
|
|
|
private static List<string> PositionToMovementSequenceEdges(IEnumerable<string> movements)
|
|
{
|
|
var allMovements = new List<string>()
|
|
{
|
|
"INSIDE_CIRCLE"
|
|
};
|
|
|
|
allMovements.AddRange(movements);
|
|
|
|
allMovements.Add("INSIDE_CIRCLE");
|
|
|
|
return allMovements;
|
|
}
|
|
|
|
private static (List<CIRCLESECTION> movements, bool startToLeft) PositionToMovementSequence(int fakeCircle, int line)
|
|
{
|
|
var movements = new List<CIRCLESECTION>();
|
|
|
|
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<string> movementActions, IEnumerable<string> 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<string> Flags { get; } = new List<string>();
|
|
public List<string> MovementActions { get; } = new List<string>();
|
|
}
|
|
|
|
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() => $"<inputKey>{KeyCodeText}</inputKey>";
|
|
public string GetActionType() => "INPUT_KEY";
|
|
}
|
|
|
|
public class StringContent : IKeyboardContent
|
|
{
|
|
public StringContent(string content)
|
|
{
|
|
Content = content;
|
|
}
|
|
|
|
public string Content { get; }
|
|
|
|
public string GetContent() => $"<inputString>{Content}</inputString>";
|
|
public string GetActionType() => "INPUT_TEXT";
|
|
}
|
|
}
|