Last active
August 2, 2020 04:15
-
-
Save koktoh/74d7fb4b20d1254129bc31692369cacd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Main() | |
{ | |
var keycordPath = @""; // common\keycode.h | |
var qkPath = @""; // quantum\quantum_keycodes.h | |
var kc = keycordPath.ToFileInfo().OpenText().ReadToEnd(); | |
var qk = qkPath.ToFileInfo().OpenText().ReadToEnd(); | |
var parser = new KeycodeDefinitionParser(); | |
var tmkKeycodes = parser.Parse(kc).ToList(); | |
var qmkKeycodes = parser.Parse(tmkKeycodes, qk).ToList(); | |
var keycodes = tmkKeycodes.Concat(qmkKeycodes).ToList(); | |
var formated = keycodes | |
.OrderBy(x => x.DefinitionValue) | |
.Select(x => $@" ""{x.Definition}"": {x.DefinitionValue}") | |
.Join($",{Environment.NewLine}"); | |
var json = new[] { "{", formated, "}", Environment.NewLine }.JoinNewLine(); | |
json.Dump(); | |
} | |
// Define other methods and classes here | |
public interface IKeycodeDefinition | |
{ | |
string Definition { get; set; } | |
int DefinitionValue { get; set; } | |
} | |
public class KeycodeDefinition : IKeycodeDefinition | |
{ | |
private readonly Regex _hexRex; | |
public string Definition { get; set; } | |
public string DefinitionValueRaw { get; set; } | |
public bool HasDefinitionValueRaw => this.DefinitionValueRaw.HasMeaningfulValue(); | |
public bool isDefinitionValueHex => this._hexRex.IsMatch(this.DefinitionValueRaw); | |
public int DefinitionValue { get; set; } | |
public KeycodeDefinition() : this(string.Empty) { } | |
public KeycodeDefinition(string definition) : this(definition, string.Empty) { } | |
public KeycodeDefinition(string definition, string definitionValueRaw) | |
{ | |
this._hexRex = new Regex(@"^0x[0-9A-Fa-f]+$"); | |
this.Definition = definition; | |
this.DefinitionValueRaw = definitionValueRaw; | |
} | |
} | |
public class KeycodeDefinitionParser | |
{ | |
private const string KC_ENUM = "kc_enum"; | |
private const string ENUM_ITEMS = "enum_items"; | |
private const string EX_KEYCODE = "ex_kc"; | |
private readonly Regex _kcEnumDefRex; | |
private readonly Regex _kcEnumItemsRex; | |
private readonly Regex _exKcRex; | |
public KeycodeDefinitionParser() | |
{ | |
this._kcEnumDefRex = new Regex($@"(\r|\n)*\s*(?<{KC_ENUM}>enum (.*(\r|\n))+?\}};)"); | |
this._kcEnumItemsRex = new Regex($@".*\{{\s*(\r|\n)(?<{ENUM_ITEMS}>(.*(\r|\n))+?)\}};"); | |
this._exKcRex = new Regex($@"\s*\#define\s(?<{EX_KEYCODE}>(([^\(\)]+?)\s([^\(\)]+?)))(\s*/.*?)?(\r|\n)"); | |
} | |
public IEnumerable<IKeycodeDefinition> Parse(string raw) | |
{ | |
return this.Parse(Enumerable.Empty<IKeycodeDefinition>(), raw); | |
} | |
public IEnumerable<IKeycodeDefinition> Parse(IEnumerable<IKeycodeDefinition> baseKeycodes, string raw) | |
{ | |
var enumDefs = this.GetKeycodeEnumDefinitions(raw); | |
var keycodes = this.GetKeycodeDefinitions(enumDefs).ToList(); | |
baseKeycodes = baseKeycodes.Concat(keycodes); | |
var exKeycodes = this.GetExKeycodes(baseKeycodes, raw).ToList(); | |
return keycodes.Concat(exKeycodes); | |
} | |
private IEnumerable<IEnumerable<KeycodeDefinition>> GetKeycodeEnumDefinitions(string raw) | |
{ | |
return this._kcEnumDefRex.Matches(raw) | |
.Cast<Match>() | |
.Select(x => x.Groups[KC_ENUM].Value) | |
.Select(x => this._kcEnumItemsRex.Match(x).Groups[ENUM_ITEMS].Value) | |
.Select(x => x.SplitNewLine().Select(y => y.Trim()).Where(y => !y.StartsWith("/") && !y.StartsWith("#") && y.HasMeaningfulValue())) | |
.Select(x => x.Select(y => y.SplitCommma().First())) | |
.Select(x => x.Select(y => y.Split("=").Select(z => z.Trim()))) | |
.Select(x => x.Select(y => | |
{ | |
var item = y.First(); | |
var value = string.Empty; | |
if (y.Count() > 1) | |
{ | |
value = y.ElementAt(1); | |
} | |
return new KeycodeDefinition(item, value); | |
})); | |
} | |
private IEnumerable<IKeycodeDefinition> GetKeycodeDefinitions(IEnumerable<IEnumerable<KeycodeDefinition>> source) | |
{ | |
var list = new List<KeycodeDefinition>(); | |
foreach (var enumDef in source) | |
{ | |
var preDef = new KeycodeDefinition(); | |
for (int i = 0; i < enumDef.Count(); i++) | |
{ | |
var def = enumDef.ElementAt(i); | |
if (def.isDefinitionValueHex) | |
{ | |
def.DefinitionValue = def.DefinitionValueRaw.HexToInt32(); | |
} | |
else if (def.HasDefinitionValueRaw) | |
{ | |
var srcDef = list.First(x => x.Definition.Equals(def.DefinitionValueRaw)); | |
def.DefinitionValue = srcDef.DefinitionValue; | |
} | |
else | |
{ | |
def.DefinitionValue = preDef.DefinitionValue + 1; | |
} | |
if (!preDef.Definition.Equals(def.Definition) || preDef.DefinitionValue < def.DefinitionValue) | |
{ | |
preDef = def; | |
} | |
list.Add(def); | |
} | |
} | |
return list; | |
} | |
private IEnumerable<IKeycodeDefinition> GetExKeycodes(IEnumerable<IKeycodeDefinition> baseKeycodes, string raw) | |
{ | |
return this._exKcRex.Matches(raw) | |
.Cast<Match>() | |
.Select(x => x.Groups[EX_KEYCODE].Value) | |
.Select(x => x.Split(' ').Select(y => y.Trim()).ToArray()) | |
.Where(x => x.Length > 1) | |
.Select(x => new KeycodeDefinition(x[0], x[1])) | |
.Where(x => x.isDefinitionValueHex || baseKeycodes.Select(y => y.Definition).Contains(x.DefinitionValueRaw)) | |
.Select(x => | |
{ | |
var def = x; | |
if (x.isDefinitionValueHex) | |
{ | |
def.DefinitionValue = x.DefinitionValueRaw.HexToInt32(); | |
} | |
else | |
{ | |
var keycode = baseKeycodes.First(y => y.Definition.Equals(x.DefinitionValueRaw)); | |
def.DefinitionValue = keycode.DefinitionValue; | |
} | |
return def; | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment