Last active
November 25, 2018 18:14
-
-
Save holly-hacker/3bce6cfa0f5349e1fcc87a4473cf7c2c to your computer and use it in GitHub Desktop.
Converts Teach2000 files to CSV and Anki's APKG format.
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
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics.CodeAnalysis; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Xml; | |
using AnkiSharp; // Import form NuGet package | |
namespace TeachConvert | |
{ | |
[SuppressMessage("ReSharper", "PossibleNullReferenceException")] | |
internal static class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
if (args.Length != 1) { | |
Console.WriteLine("Pass me a folder containing .t2k files."); | |
Console.WriteLine("If you don't know how, just drag the folder on this exe."); | |
Console.ReadLine(); | |
return; | |
} | |
string path = args[0]; | |
if (!Directory.Exists(path)) { | |
Console.WriteLine("Passed argument is not a directory."); | |
Console.ReadLine(); | |
return; | |
} | |
foreach (string filePath in Directory.EnumerateFiles(path, "*.t2k", SearchOption.AllDirectories)) { | |
try { | |
string folder = Path.GetDirectoryName(filePath); | |
string file = Path.GetFileName(filePath); | |
string fileClean = Path.GetFileNameWithoutExtension(filePath); | |
var dic = LoadFile(filePath); | |
Console.WriteLine($"Loaded {dic.Count} lines from {file}."); | |
WriteCsv(Path.Combine(folder, fileClean + ".csv"), dic); | |
WriteAnki(Path.Combine(folder, fileClean + ".apkg"), dic, fileClean); | |
} catch (Exception e) { | |
Console.WriteLine($"! Failed to process {filePath}, {e.Message}"); | |
} | |
} | |
} | |
private static void WriteAnki(string outFile, Dictionary<string, string> dic, string packageName) | |
{ | |
var anki = new Anki(packageName); | |
foreach (var pair in dic) | |
anki.AddItem(pair.Key, pair.Value); | |
anki.CreateApkgFile(Path.GetDirectoryName(outFile)); // quality API design, AnkiSharp :( | |
} | |
private static void WriteCsv(string outFile, Dictionary<string, string> dic) | |
{ | |
const char separator = ','; | |
string Escaped(string s) => $"\"{s}\""; // csv is weird, man | |
using (var sw = new StreamWriter(outFile, false, Encoding.Unicode)) { // using UTF16 is the only way to make Excel happy :( | |
sw.WriteLine($"Question{separator}Answer"); | |
foreach (var pair in dic) { | |
sw.WriteLine(Escaped(pair.Key) + separator + Escaped(pair.Value)); | |
} | |
} | |
} | |
private static Dictionary<string, string> LoadFile(string path) | |
{ | |
var dic = new Dictionary<string, string>(); | |
var doc = new XmlDocument(); | |
doc.Load(path); | |
var items = doc.DocumentElement.SelectNodes("/teach2000/message_data/items/item"); | |
foreach (XmlElement elem in items) { | |
var ql = elem.SelectNodes("questions/question"); | |
var al = elem.SelectNodes("answers/answer"); | |
var q = string.Join("/", ql.OfType<XmlElement>().Select(x => x.InnerText)); | |
var a = string.Join("/", al.OfType<XmlElement>().Select(x => x.InnerText)); | |
// Console.WriteLine($"{q};{a}"); | |
dic[q] = a; | |
} | |
return dic; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment