Make hint foundries configurable

Resolves #173

and the milestone from, originally, 1 Apr 2025

Change-Id: Iaa062ae4831187c96f99f339b29cc4374cc31afd
diff --git a/dev/js/src/default.js b/dev/js/src/default.js
index 344feac..39d211e 100644
--- a/dev/js/src/default.js
+++ b/dev/js/src/default.js
@@ -1,5 +1,15 @@
+/**
+ * Default foundries to include in the Kalamar JavaScript bundle.
+ * The actual foundries shown at runtime are controlled by the
+ * hint_foundries configuration or KALAMAR_HINT_FOUNDRIES env var.
+ */
 require([
   "hint/foundries/base",
-  "hint/foundries/ud",
-  "hint/foundries/dereko"
+  "hint/foundries/corenlp",
+  "hint/foundries/dereko",
+  "hint/foundries/malt",
+  "hint/foundries/marmot",
+  "hint/foundries/opennlp",
+  "hint/foundries/spacy",
+  "hint/foundries/treetagger"
 ]);
diff --git a/dev/js/src/hint.js b/dev/js/src/hint.js
index de9c09b..bcdd6a6 100644
--- a/dev/js/src/hint.js
+++ b/dev/js/src/hint.js
@@ -64,6 +64,11 @@
         console.log("No annotationhelper defined");
         return;
       };
+
+      // Apply configured foundry filter from data-hint-foundries attribute
+      if (KorAP.annotationHelper.filterByConfig) {
+        KorAP.annotationHelper.filterByConfig();
+      };
       
       /**
        * @define {regex} Regular expression for context
diff --git a/dev/js/src/hint/foundries.js b/dev/js/src/hint/foundries.js
index 80d7332..053954e 100644
--- a/dev/js/src/hint/foundries.js
+++ b/dev/js/src/hint/foundries.js
@@ -80,5 +80,32 @@
     return '';
   };
 
+  /**
+   * Filter available foundries based on configuration.
+   * Reads from data-hint-foundries attribute on body element.
+   * Each foundry module pushes entries like ["Name", "prefix/", "Description"]
+   * to ah["-"]. The prefix (e.g., "corenlp/") is matched against enabled list.
+   */
+  ah.filterByConfig = function () {
+    const body = document.body;
+    if (!body) return;
+    
+    const configAttr = body.getAttribute('data-hint-foundries');
+    if (!configAttr) return; // No filter - show all
+    
+    const enabledFoundries = configAttr.split(',').map(f => f.trim().toLowerCase());
+    if (enabledFoundries.length === 0) return;
+
+    // Filter the root foundry list ah["-"]
+    // Each entry is ["Name", "prefix/", "Description"]
+    // Match prefix (without trailing /) against enabled list
+    this["-"] = this["-"].filter(entry => {
+      if (!entry || !entry[1]) return false;
+      // Extract foundry name from prefix like "corenlp/" -> "corenlp"
+      const foundryName = entry[1].replace(/\/$/, '').toLowerCase();
+      return enabledFoundries.includes(foundryName);
+    });
+  };
+
   return ah;
 });