Skip to content

Instantly share code, notes, and snippets.

@holly-hacker
Last active November 25, 2018 18:14
Show Gist options
  • Select an option

  • Save holly-hacker/3bce6cfa0f5349e1fcc87a4473cf7c2c to your computer and use it in GitHub Desktop.

Select an option

Save holly-hacker/3bce6cfa0f5349e1fcc87a4473cf7c2c to your computer and use it in GitHub Desktop.

Revisions

  1. holly-hacker revised this gist Nov 25, 2018. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion TeachConvert.cs
    Original file line number Diff line number Diff line change
    @@ -55,7 +55,6 @@ private static void WriteAnki(string outFile, Dictionary<string, string> dic, st
    private static void WriteCsv(string outFile, Dictionary<string, string> dic)
    {
    const char separator = ',';
    // string Escaped(string s) => s.Replace(separator.ToString(), $"\"{separator}\""); // csv is weird, man
    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 :(
  2. holly-hacker created this gist Nov 25, 2018.
    90 changes: 90 additions & 0 deletions TeachConvert.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    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.Replace(separator.ToString(), $"\"{separator}\""); // csv is weird, man
    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;
    }
    }
    }