diff --git a/flake.lock b/flake.lock index 3cb02d4..009a834 100644 --- a/flake.lock +++ b/flake.lock @@ -36,6 +36,22 @@ "url": "https://www.edrdg.org/kanjidic/kanjidic2.xml.gz" } }, + "kanjivg-src": { + "flake": false, + "locked": { + "lastModified": 1772352482, + "narHash": "sha256-8EG3Y1daI2B24NELQwU+eXl/7OmWnW/RXMAQSRVLzWw=", + "ref": "refs/heads/master", + "rev": "0b4309cf6d74799b0e4b72940d8267fbe73f72d0", + "revCount": 2212, + "type": "git", + "url": "https://git.pvv.ntnu.no/mugiten/kanjivg.git" + }, + "original": { + "type": "git", + "url": "https://git.pvv.ntnu.no/mugiten/kanjivg.git" + } + }, "nixpkgs": { "locked": { "lastModified": 1771848320, @@ -68,6 +84,7 @@ "jmdict-src": "jmdict-src", "jmdict-with-examples-src": "jmdict-with-examples-src", "kanjidic2-src": "kanjidic2-src", + "kanjivg-src": "kanjivg-src", "nixpkgs": "nixpkgs", "radkfile-src": "radkfile-src" } diff --git a/flake.nix b/flake.nix index 77fbd98..9e2b57f 100644 --- a/flake.nix +++ b/flake.nix @@ -24,6 +24,11 @@ url = "https://www.edrdg.org/kanjidic/kanjidic2.xml.gz"; flake = false; }; + + kanjivg-src = { + url = "git+https://git.pvv.ntnu.no/mugiten/kanjivg.git"; + flake = false; + }; }; outputs = { @@ -32,7 +37,8 @@ jmdict-src, jmdict-with-examples-src, radkfile-src, - kanjidic2-src + kanjidic2-src, + kanjivg-src, }: let inherit (nixpkgs) lib; systems = [ diff --git a/lib/_data_ingestion/kanjivg/objects.dart b/lib/_data_ingestion/kanjivg/objects.dart new file mode 100644 index 0000000..b09eaa7 --- /dev/null +++ b/lib/_data_ingestion/kanjivg/objects.dart @@ -0,0 +1,92 @@ +import 'package:jadb/_data_ingestion/sql_writable.dart'; + +/// Enum set in the kvg:position attribute, used by `` elements in the KanjiVG SVG files. +enum KanjiPathGroupPosition { + bottom, + kamae, + kamaec, + left, + middle, + nyo, + nyoc, + right, + tare, + tarec, + top, +} + +/// Contents of a \ element in the KanjiVG SVG files. +class KanjiPathGroupTreeNode extends SQLWritable { + final String id; + final List children; + final String? element; + final String? original; + final KanjiPathGroupPosition? position; + final String? radical; + final int? part; + + KanjiPathGroupTreeNode({ + required this.id, + this.children = const [], + this.element, + this.original, + this.position, + this.radical, + this.part, + }); + + @override + Map get sqlValue => { + 'id': id, + 'element': element, + 'original': original, + 'position': position?.name, + 'radical': radical, + 'part': part, + }; +} + +/// Contents of a `` element in the StrokeNumber's group in the KanjiVG SVG files +class KanjiStrokeNumber extends SQLWritable { + final int num; + final double x; + final double y; + + KanjiStrokeNumber(this.num, this.x, this.y); + + @override + Map get sqlValue => {'num': num, 'x': x, 'y': y}; +} + +/// Contents of a `` element in the KanjiVG SVG files +class KanjiVGPath extends SQLWritable { + final String id; + final String type; + final String svgPath; + + KanjiVGPath({required this.id, required this.type, required this.svgPath}); + + @override + Map get sqlValue => { + 'id': id, + 'type': type, + 'svgPath': svgPath, + }; +} + +class KanjiVGItem extends SQLWritable { + final String character; + final List paths; + final List strokeNumbers; + final List pathGroups; + + KanjiVGItem({ + required this.character, + required this.paths, + required this.strokeNumbers, + required this.pathGroups, + }); + + @override + Map get sqlValue => {'character': character}; +} diff --git a/lib/_data_ingestion/kanjivg/seed_data.dart b/lib/_data_ingestion/kanjivg/seed_data.dart new file mode 100644 index 0000000..8d9860f --- /dev/null +++ b/lib/_data_ingestion/kanjivg/seed_data.dart @@ -0,0 +1,7 @@ +import 'package:sqflite_common/sqflite.dart'; + +Future seedKanjiVGData(Iterable xmlContents, Database db) async { + final b = db.batch(); + + await b.commit(noResult: true); +} diff --git a/lib/models/verify_tables.dart b/lib/models/verify_tables.dart index fe5c955..23a5559 100644 --- a/lib/models/verify_tables.dart +++ b/lib/models/verify_tables.dart @@ -1,5 +1,6 @@ import 'package:jadb/table_names/jmdict.dart'; import 'package:jadb/table_names/kanjidic.dart'; +import 'package:jadb/table_names/kanjivg.dart'; import 'package:jadb/table_names/radkfile.dart'; import 'package:jadb/table_names/tanos_jlpt.dart'; import 'package:sqflite_common/sqlite_api.dart'; @@ -21,6 +22,7 @@ Future verifyTablesWithDbConnection(DatabaseExecutor db) async { ...KANJIDICTableNames.allTables, ...RADKFILETableNames.allTables, ...TanosJLPTTableNames.allTables, + ...KanjiVGTableNames.allTables, }; final missingTables = expectedTables.difference(tables); diff --git a/lib/table_names/kanjivg.dart b/lib/table_names/kanjivg.dart new file mode 100644 index 0000000..cee9e41 --- /dev/null +++ b/lib/table_names/kanjivg.dart @@ -0,0 +1,9 @@ +abstract class KanjiVGTableNames { + static const String version = 'KanjiVG_Version'; + static const String entry = 'KanjiVG_Entry'; + static const String path = 'KanjiVG_Path'; + static const String strokeNumber = 'KanjiVG_StrokeNumber'; + static const String pathGroup = 'KanjiVG_PathGroup'; + + static Set get allTables => {version, entry, path, strokeNumber, pathGroup}; +} diff --git a/migrations/0011_KanjiVG.sql b/migrations/0011_KanjiVG.sql new file mode 100644 index 0000000..5a40713 --- /dev/null +++ b/migrations/0011_KanjiVG.sql @@ -0,0 +1,45 @@ +CREATE TABLE "KanjiVG_Version" ( + "version" VARCHAR(10) PRIMARY KEY NOT NULL, + "date" DATE NOT NULL, + "hash" VARCHAR(64) NOT NULL +) WITHOUT ROWID; + +CREATE TRIGGER "KanjiVG_Version_SingleRow" +BEFORE INSERT ON "KanjiVG_Version" +WHEN (SELECT COUNT(*) FROM "KanjiVG_Version") >= 1 +BEGIN + SELECT RAISE(FAIL, 'Only one row allowed in KanjiVG_Version'); +END; + +CREATE TABLE "KanjiVG_Entry" ( + "character" CHAR(1) PRIMARY KEY NOT NULL +) WITHOUT ROWID; + +CREATE TABLE "KanjiVG_StrokeNumber" ( + "character" CHAR(1) NOT NULL REFERENCES "KanjiVG_Entry"("character"), + "strokeNum" INTEGER NOT NULL, + "x" REAL NOT NULL, + "y" REAL NOT NULL, + PRIMARY KEY ("character", "strokeNum") +) WITHOUT ROWID; + +CREATE TABLE "KanjiVG_Path" ( + "character" CHAR(1) NOT NULL REFERENCES "KanjiVG_Entry"("character"), + "pathId" TEXT NOT NULL, + "type" VARCHAR(10) NOT NULL, + "svgPath" TEXT NOT NULL, + PRIMARY KEY ("character", "pathId") +) WITHOUT ROWID; + +CREATE TABLE "KanjiVG_PathGroup" ( + "character" CHAR(1) NOT NULL REFERENCES "KanjiVG_Entry"("character"), + "groupId" TEXT NOT NULL, + "parentGroupId" TEXT REFERENCES "KanjiVG_PathGroup"("groupId"), + "element" TEXT, + "original" TEXT, + "position" VARCHAR(10), + "radical" TEXT, + "part" INTEGER, + PRIMARY KEY ("character", "groupId"), + CHECK ("position" IN ('bottom', 'kamae', 'kamaec', 'left', 'middle', 'nyo', 'nyoc', 'right', 'tare', 'tarec', 'top') OR "position" IS NULL) +) WITHOUT ROWID;