ripose-jp / Memento

An mpv-based video player for studying Japanese
https://ripose-jp.github.io/Memento/
GNU General Public License v2.0
472 stars 22 forks source link

null tags are unsupported in term banks #165

Closed precondition closed 1 year ago

precondition commented 1 year ago

Setting null as the tags field (index 2) for a term in a term bank causes an error because Memento expects a string.

Example taken from an entry in 明鏡国語辞典第二阪:

Expected index 2 to be of type string
[
  "亜",
  "あ",
  null,
  "",
  0,
  [
    {
      "type":"structured-content",
      "content":[
        "あ【亜】\n(造)\n① 次ぐ。第二の。\n「━鉛・━流・━熱帯」\n② 「亜細亜",
        {
          "tag":"span",
          "style":{
            "fontSize":"small",
            "verticalAlign":"sub"
          },
          "data":{
            "meikyo":"furigana"
          },
          "content":"(アジア)"
        },
        "」の略。\n「大東━・欧━」\n◆[表記]「",
        {
          "tag":"ruby",
          "content":[
            "堊",
            {
              "tag":"rt",
              "content":"▼"
            }
          ]
        },
        "」の代用字とする(白亜)。\n[旧]亞"
      ]
    }
  ],
  2,
  ""
]
Could not add term_bank_1.json

According to the dictionary term bank v3 schema, null is a perfectly valid value which is equivalent to "".

PS: This is not exclusive to the v3, the v1 also has that requirement.

precondition commented 1 year ago

This patch fixes the issue but it causes superfluous error messages if the DEF_TAGS are null:

diff --git a/src/dict/yomidbbuilder.c b/src/dict/yomidbbuilder.c
index 732a12e..5889b26 100644
--- a/src/dict/yomidbbuilder.c
+++ b/src/dict/yomidbbuilder.c
@@ -997,8 +997,20 @@ static int add_term(sqlite3 *db, json_object *term, const sqlite3_int64 id)
     reading = json_object_get_string(ret_obj);

     if ((ret = get_obj_from_array(term, DEF_TAGS_INDEX, json_type_string, &ret_obj)))
-        goto cleanup;
-    def_tags = json_object_get_string(ret_obj);
+    {
+        if (json_object_is_type(ret_obj, json_type_null))
+        {
+            def_tags = "";
+        }
+        else
+        {
+            goto cleanup;
+        }
+    }
+    else
+    {
+        def_tags = json_object_get_string(ret_obj);  // non-null JSON string
+    }

     if ((ret = get_obj_from_array(term, RULES_INDEX, json_type_string, &ret_obj)))
         goto cleanup;

EDIT: See linked PR for a better patch.