From 706ce7a272443cfc468867683d61efdeb3c09f6f Mon Sep 17 00:00:00 2001
From: darrylong <darrylong@users.noreply.github.com>
Date: Tue, 30 Jul 2024 10:47:59 +0800
Subject: [PATCH] Add multimodality table to documentation (#639)

---
 docs/generate_model_js.py                     | 170 +++---
 docs/source/_static/models/data.js            | 488 ++++++++++++++++++
 docs/source/_static/models/models.html        |   4 +-
 .../_static/models/models_modalities.html     | 118 +++++
 docs/source/conf.py                           |  10 +
 docs/source/index.rst                         |  10 +-
 docs/source/models/index.rst                  |   5 +-
 7 files changed, 741 insertions(+), 64 deletions(-)
 create mode 100644 docs/source/_static/models/models_modalities.html

diff --git a/docs/generate_model_js.py b/docs/generate_model_js.py
index ba894314..1c720c14 100644
--- a/docs/generate_model_js.py
+++ b/docs/generate_model_js.py
@@ -1,5 +1,6 @@
 import json
-
+import os
+import glob
 
 def get_key_val(part):
     key_index_start = part.index('[')
@@ -13,48 +14,8 @@ def get_key_val(part):
     return key, val
 
 
-# Read the content from README.md
-with open('../README.md', 'r') as file:
-    content = file.read()
-
-# Extract the relevant information from the content
-models = []
-lines = content.split('\n')
-lines = lines[lines.index('## Models') + 4: lines.index('## Resources') - 2]
-
-headers = []
-headers = lines[0].split('|')[1:-1]
-headers = [header.strip() for header in headers]
-
-for line in lines[2:]:
-    parts = line.split('|')[1:-1]
-    parts = [part.strip() for part in parts]
-    model = dict(zip(headers, parts))
-    models.append(model)
-
-year = None
-
-for model in models:
-    # handle empty years
-    if model["Year"] == "":
-        model["Year"] = year
-    else:
-        year = model["Year"]
-        
-    # handle model, docs and paper part
-    name_paper_str = model["Model and Paper"]
-
-    for i, part in enumerate(name_paper_str.split(', ')):
-        key, val = get_key_val(part)
-
-        if i == 0:
-            model["Name"] = key
-            model["Link"] = val
-        else:
-            model[key] = val
-    
+def add_pytorch_tensorflow(model):
     # handle environment part
-    
     env_part = model["Environment"].split(', ')[0]
     
     search_dict = {
@@ -74,28 +35,117 @@ for model in models:
     else:
         for header, _ in search_dict.items():
             model[header] = False
+
+
+def add_modalities_for_model(model):
+    modalities_keywords = {
+        "User Text": "user_text",
+        "User Image": "user_image",
+        "User Graph": "user_graph",
+        "Item Text": "item_text",
+        "Item Image": "item_image",
+        "Item Graph": "item_graph",
+        "Sentiment": "sentiment",
+        "Review Text": "review_text",
+    }
     
-    # remove non required keys
-    model.pop("Model and Paper")
-    model.pop("Environment")
-    
-    # Get package name
-    model_dir = model["Link"]
+    for filename in glob.glob(f'../{model["Link"]}/*.py', recursive=True):
+        with open(filename, 'r') as file:
+            file_data = file.read()
+            
+            for header, modality_keyword in modalities_keywords.items():
+                is_found = modality_keyword in file_data
+                if is_found:
+                    model[header] = True
+            
+            # for user feature and item feature
+            # >> if user feature is found, we set user text, image and graph to true
+            is_found = "user_feature" in file_data
+            if is_found:
+                model["User Text"] = True
+                model["User Image"] = True
+                model["User Graph"] = True
+                
+            # likewise for item feature
+            is_found = "item_feature" in file_data
+            if is_found:
+                model["Item Text"] = True
+                model["Item Image"] = True
+                model["Item Graph"] = True
     
-    with open(f'../{model_dir}/__init__.py', 'r') as file:
-        init_data = file.read()
+    for header, modality_keyword in modalities_keywords.items():
+        if header not in model:
+            model[header] = False
+
+
+if __name__ == "__main__":
+    # Read the content from README.md
+    with open('../README.md', 'r') as file:
+        content = file.read()
+
+    # Extract the relevant information from the content
+    models = []
+    lines = content.split('\n')
+    lines = lines[lines.index('## Models') + 4: lines.index('## Resources') - 2]
+
+    headers = []
+    headers = lines[0].split('|')[1:-1]
+    headers = [header.strip() for header in headers]
+
+    for line in lines[2:]:
+        parts = line.split('|')[1:-1]
+        parts = [part.strip() for part in parts]
+        model = dict(zip(headers, parts))
+        models.append(model)
+
+    year = None
+
+    for model in models:
+        # handle empty years
+        if model["Year"] == "":
+            model["Year"] = year
+        else:
+            year = model["Year"]
+            
+        # handle model, docs and paper part
+        name_paper_str = model["Model and Paper"]
+
+        for i, part in enumerate(name_paper_str.split(', ')):
+            key, val = get_key_val(part)
+
+            if i == 0:
+                model["Name"] = key
+                model["Link"] = val
+            else:
+                model[key] = val
         
-        package_names = []
+        # Check for PyTorch and TensorFlow in each requirements file
+        add_pytorch_tensorflow(model)
         
-        for row in init_data.split('\n'):
-            if "import" in row:
-                package_name = row[row.index("import") + len("import "):]
-                package_names.append(f"cornac.models.{package_name}")
+        # Check for modalities keywords in files and add to model
+        add_modalities_for_model(model)
+                    
+        # remove non required keys
+        model.pop("Model and Paper")
+        model.pop("Environment")
         
-        model["packages"] = package_names
+        # Get package name
+        model_dir = model["Link"]
+        
+        with open(f'../{model_dir}/__init__.py', 'r') as file:
+            init_data = file.read()
+            
+            package_names = []
+            
+            for row in init_data.split('\n'):
+                if "import" in row:
+                    package_name = row[row.index("import") + len("import "):]
+                    package_names.append(f"cornac.models.{package_name}")
+            
+            model["packages"] = package_names
 
-json_str = json.dumps(models, indent=4)
+    json_str = json.dumps(models, indent=4)
 
-# Write the JSON object to a file
-with open('source/_static/models/data.js', 'w') as file:
-    file.write(f"var data = {json_str};")
+    # Write the JSON object to a file
+    with open('source/_static/models/data.js', 'w') as file:
+        file.write(f"var data = {json_str};")
diff --git a/docs/source/_static/models/data.js b/docs/source/_static/models/data.js
index 678a72bb..1191f1f4 100644
--- a/docs/source/_static/models/data.js
+++ b/docs/source/_static/models/data.js
@@ -8,6 +8,14 @@ var data = [
         "paper": "https://doi.org/10.1007/978-3-031-56027-9_14",
         "PyTorch": true,
         "TensorFlow": false,
+        "Sentiment": true,
+        "Review Text": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
         "packages": [
             "cornac.models.HypAR"
         ]
@@ -21,6 +29,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/2203.05406.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "Item Text": true,
+        "Item Image": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.DMRL"
         ]
@@ -34,6 +50,14 @@ var data = [
         "paper": "https://dl.acm.org/doi/pdf/10.1145/3437963.3441759",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": true,
+        "User Image": true,
+        "User Graph": true,
+        "Item Text": true,
+        "Item Image": true,
+        "Item Graph": true,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.BiVAECF"
         ]
@@ -47,6 +71,14 @@ var data = [
         "paper": "https://arxiv.org/abs/2107.02390",
         "PyTorch": true,
         "TensorFlow": false,
+        "Item Image": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.CausalRec"
         ]
@@ -60,6 +92,14 @@ var data = [
         "paper": "https://dl.acm.org/doi/pdf/10.1145/3437963.3441754",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.ComparERSub",
             "cornac.models.ComparERObj"
@@ -74,6 +114,14 @@ var data = [
         "paper": "https://ieeexplore.ieee.org/document/8618394",
         "PyTorch": true,
         "TensorFlow": false,
+        "Item Image": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.AMR"
         ]
@@ -87,6 +135,14 @@ var data = [
         "paper": "https://www.sciencedirect.com/science/article/abs/pii/S0925231219313207",
         "PyTorch": false,
         "TensorFlow": true,
+        "User Text": true,
+        "Item Text": true,
+        "Review Text": true,
+        "User Image": false,
+        "User Graph": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
         "packages": [
             "cornac.models.HRDR"
         ]
@@ -100,6 +156,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/2002.02126.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.LightGCN"
         ]
@@ -113,6 +177,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/2006.11483.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.DNNTSP"
         ]
@@ -126,6 +198,14 @@ var data = [
         "paper": "https://dl.acm.org/doi/abs/10.1145/3340631.3394850",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.UPCF"
         ]
@@ -139,6 +219,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/2006.00556.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.TIFUKNN"
         ]
@@ -152,6 +240,14 @@ var data = [
         "paper": "https://doi.org/10.1145/3336191.3371831",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.RecVAE"
         ]
@@ -165,6 +261,14 @@ var data = [
         "paper": "https://www.ijcai.org/proceedings/2019/0389.pdf",
         "PyTorch": false,
         "TensorFlow": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.Beacon"
         ]
@@ -178,6 +282,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1905.03375.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.EASE"
         ]
@@ -191,6 +303,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1905.08108.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.NGCF"
         ]
@@ -204,6 +324,14 @@ var data = [
         "paper": "https://www.ijcai.org/proceedings/2018/0370.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "Item Graph": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.C2PF"
         ]
@@ -217,6 +345,14 @@ var data = [
         "paper": "https://www.kdd.org/kdd2018/files/deep-learning-day/DLDay18_paper_32.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Graph": true,
+        "User Text": false,
+        "User Image": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.GCMC"
         ]
@@ -230,6 +366,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1806.03568.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.MTER"
         ]
@@ -243,6 +387,14 @@ var data = [
         "paper": "http://www.thuir.cn/group/~YQLiu/publications/WWW2018_CC.pdf",
         "PyTorch": false,
         "TensorFlow": true,
+        "Review Text": true,
+        "User Text": true,
+        "Item Text": true,
+        "User Image": false,
+        "User Graph": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
         "packages": [
             "cornac.models.NARRE"
         ]
@@ -256,6 +408,14 @@ var data = [
         "paper": "http://www.hadylauw.com/publications/uai18.pdf",
         "PyTorch": false,
         "TensorFlow": true,
+        "Item Graph": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.PCRL"
         ]
@@ -269,6 +429,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1802.05814.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.VAECF"
         ]
@@ -282,6 +450,14 @@ var data = [
         "paper": "http://eelxpeng.github.io/assets/paper/Collaborative_Variational_Autoencoder.pdf",
         "PyTorch": false,
         "TensorFlow": true,
+        "Item Text": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.CVAE"
         ]
@@ -295,6 +471,14 @@ var data = [
         "paper": "https://dl.acm.org/doi/10.1145/3132847.3132972",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Graph": true,
+        "User Text": false,
+        "User Image": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.CVAECF"
         ]
@@ -308,6 +492,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1708.05031.pdf",
         "PyTorch": true,
         "TensorFlow": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.GMF",
             "cornac.models.MLP",
@@ -323,6 +515,14 @@ var data = [
         "paper": "http://www.hadylauw.com/publications/cikm17a.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.IBPR"
         ]
@@ -336,6 +536,14 @@ var data = [
         "paper": "https://dsail.kaist.ac.kr/files/WWW17.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "Item Graph": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.MCF"
         ]
@@ -349,6 +557,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1708.05031.pdf",
         "PyTorch": true,
         "TensorFlow": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.GMF",
             "cornac.models.MLP",
@@ -364,6 +580,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1708.05031.pdf",
         "PyTorch": true,
         "TensorFlow": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.GMF",
             "cornac.models.MLP",
@@ -379,6 +603,14 @@ var data = [
         "paper": "http://www.hadylauw.com/publications/cikm17a.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.OnlineIBPR"
         ]
@@ -392,6 +624,14 @@ var data = [
         "paper": "https://dsail.kaist.ac.kr/files/WWW17.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "Item Image": true,
+        "Item Text": true,
+        "Item Graph": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.VMF"
         ]
@@ -405,6 +645,14 @@ var data = [
         "paper": "http://inpluslab.com/chenliang/homepagefiles/paper/hao-pakdd2016.pdf",
         "PyTorch": false,
         "TensorFlow": true,
+        "Item Text": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.CDR"
         ]
@@ -418,6 +666,14 @@ var data = [
         "paper": "http://www.hadylauw.com/publications/sdm16.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.COE"
         ]
@@ -431,6 +687,14 @@ var data = [
         "paper": "http://uclab.khu.ac.kr/resources/publication/C_351.pdf",
         "PyTorch": false,
         "TensorFlow": true,
+        "Item Text": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.ConvMF"
         ]
@@ -444,6 +708,14 @@ var data = [
         "paper": "https://www.yongfeng.me/attach/sigir16-chen.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.LRPPM"
         ]
@@ -457,6 +729,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1511.06939.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.GRU4Rec"
         ]
@@ -470,6 +750,14 @@ var data = [
         "paper": "https://www.sciencedirect.com/science/article/pii/S092523121501509X",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.SKMeans"
         ]
@@ -483,6 +771,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1510.01784.pdf",
         "PyTorch": true,
         "TensorFlow": false,
+        "Item Image": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.VBPR"
         ]
@@ -496,6 +792,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1409.2944.pdf",
         "PyTorch": false,
         "TensorFlow": true,
+        "Item Text": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.CDL"
         ]
@@ -509,6 +813,14 @@ var data = [
         "paper": "http://jakehofman.com/inprint/poisson_recs.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.HPF"
         ]
@@ -522,6 +834,14 @@ var data = [
         "paper": "https://wing.comp.nus.edu.sg/wp-content/uploads/Publications/PDF/TriRank-%20Review-aware%20Explainable%20Recommendation%20by%20Modeling%20Aspects.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "Sentiment": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.TriRank"
         ]
@@ -535,6 +855,14 @@ var data = [
         "paper": "https://www.yongfeng.me/attach/efm-zhang.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.EFM"
         ]
@@ -548,6 +876,14 @@ var data = [
         "paper": "https://cseweb.ucsd.edu/~jmcauley/pdfs/cikm14.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.SBPR"
         ]
@@ -561,6 +897,14 @@ var data = [
         "paper": "https://cs.stanford.edu/people/jure/pubs/reviews-recsys13.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "Item Text": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.HFT"
         ]
@@ -574,6 +918,14 @@ var data = [
         "paper": "http://proceedings.mlr.press/v18/gantner12a/gantner12a.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.BPR",
             "cornac.models.WBPR"
@@ -588,6 +940,14 @@ var data = [
         "paper": "http://www.cs.columbia.edu/~blei/papers/WangBlei2011.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "Item Text": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.CTR"
         ]
@@ -601,6 +961,14 @@ var data = [
         "paper": "http://courses.ischool.berkeley.edu/i290-dm/s11/SECURE/a1-koren.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.BaselineOnly"
         ]
@@ -613,6 +981,14 @@ var data = [
         "docs": "https://arxiv.org/ftp/arxiv/papers/1205/1205.2618.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.BPR",
             "cornac.models.WBPR"
@@ -627,6 +1003,14 @@ var data = [
         "paper": "https://www.csie.ntu.edu.tw/~b97053/paper/Factorization%20Machines%20with%20libFM.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.FM"
         ]
@@ -640,6 +1024,14 @@ var data = [
         "paper": "https://datajobs.com/data-science-repo/Recommender-Systems-[Netflix].pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.GlobalAvg"
         ]
@@ -652,6 +1044,14 @@ var data = [
         "paper": "https://dl.acm.org/doi/pdf/10.1145/3587153",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.GPTop"
         ]
@@ -665,6 +1065,14 @@ var data = [
         "paper": "https://dl.acm.org/doi/pdf/10.1145/371920.372071",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.ItemKNN",
             "cornac.models.UserKNN"
@@ -679,6 +1087,14 @@ var data = [
         "paper": "https://datajobs.com/data-science-repo/Recommender-Systems-[Netflix].pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.MF"
         ]
@@ -692,6 +1108,14 @@ var data = [
         "paper": "https://link.springer.com/content/pdf/10.1007/s10994-008-5073-7.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.MMMF"
         ]
@@ -705,6 +1129,14 @@ var data = [
         "paper": "https://arxiv.org/ftp/arxiv/papers/1205/1205.2618.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.MostPop"
         ]
@@ -718,6 +1150,14 @@ var data = [
         "paper": "http://papers.nips.cc/paper/1861-algorithms-for-non-negative-matrix-factorization.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.NMF"
         ]
@@ -731,6 +1171,14 @@ var data = [
         "paper": "https://papers.nips.cc/paper/3208-probabilistic-matrix-factorization.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.PMF"
         ]
@@ -744,6 +1192,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1511.06939.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.SPop"
         ]
@@ -757,6 +1213,14 @@ var data = [
         "paper": "https://people.engr.tamu.edu/huangrh/Spring16/papers_course/matrix_factorization.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.SVD"
         ]
@@ -770,6 +1234,14 @@ var data = [
         "paper": "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.304.2464&rep=rep1&type=pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Graph": true,
+        "User Text": false,
+        "User Image": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.SoRec"
         ]
@@ -783,6 +1255,14 @@ var data = [
         "paper": "https://arxiv.org/pdf/1301.7363.pdf",
         "PyTorch": false,
         "TensorFlow": false,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.ItemKNN",
             "cornac.models.UserKNN"
@@ -797,6 +1277,14 @@ var data = [
         "paper": "http://yifanhu.net/PUB/cf.pdf",
         "PyTorch": false,
         "TensorFlow": true,
+        "User Text": false,
+        "User Image": false,
+        "User Graph": false,
+        "Item Text": false,
+        "Item Image": false,
+        "Item Graph": false,
+        "Sentiment": false,
+        "Review Text": false,
         "packages": [
             "cornac.models.WMF"
         ]
diff --git a/docs/source/_static/models/models.html b/docs/source/_static/models/models.html
index 3e2af8b4..316af4a9 100644
--- a/docs/source/_static/models/models.html
+++ b/docs/source/_static/models/models.html
@@ -127,12 +127,12 @@
             { 
                 field: "PyTorch", 
                 headerName: "PyTorch",
-                cellRenderer: params => params.value ? "✅" : "❌",
+                cellRenderer: params => params.value ? "✅" : "",
             },
             { 
                 field: "TensorFlow",
                 headerName: "TensorFlow",
-                cellRenderer: params => params.value ? "✅" : "❌",
+                cellRenderer: params => params.value ? "✅" : "",
             },
         ],
         defaultColDef: {
diff --git a/docs/source/_static/models/models_modalities.html b/docs/source/_static/models/models_modalities.html
new file mode 100644
index 00000000..cdba5491
--- /dev/null
+++ b/docs/source/_static/models/models_modalities.html
@@ -0,0 +1,118 @@
+<html lang="en">
+ <head>
+   <script src="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/ag-grid-community.min.js"></script>
+ </head>
+ <body>
+    <h3>Models with Modalities</h3>
+    <br />
+    <div id="modalityGrid" class="ag-theme-quartz-auto-dark" style="height: 500px"></div>
+ </body>
+</html>
+<script type="text/javascript" src="data.js"></script>
+<script type="text/javascript" src="../_static/models/data.js"></script>
+<script type="text/javascript" src="_static/models/data.js"></script>
+<script type="text/javascript">
+    function LinkRenderer(url, title) {
+        return `<a href="${url}" target="_blank">${title}</a>`
+    }
+    // Grid API: Access to Grid API methods
+    let modalityGridApi;
+
+    // Grid Options: Contains all of the grid configurations
+    const modalityGridOptions = {
+        // Data to be displayed
+        rowData: data,
+        // Columns to be displayed (Should match rowData properties)
+        columnDefs: [
+            { field: "Year" },
+            { 
+                field: "Name",
+                headerName: "Model Name (Hover over for package name)",
+                
+                flex: 4,
+                cellRenderer: params => LinkRenderer(params.data.docs, params.data.Name),
+                tooltipValueGetter: (params) => "Package Name: " + params.data.packages,
+            },
+            {
+                headerName: "Text",
+                children: [
+                    {
+                        field: "User Text",
+                        headerName: "User",
+                        cellRenderer: params => params.value ? "✅" : "",
+                    },
+                    {
+                        field: "Item Text",
+                        headerName: "Item",
+                        cellRenderer: params => params.value ? "✅" : "",
+                    },
+                ]
+            },
+            {
+                headerName: "Image",
+                children: [
+                    {
+                        field: "User Image",
+                        headerName: "User",
+                        cellRenderer: params => params.value ? "✅" : "",
+                    },
+                    {
+                        field: "Item Image",
+                        headerName: "Item",
+                        cellRenderer: params => params.value ? "✅" : "",
+                    },
+                ]
+            },
+            {
+                headerName: "Graph",
+                children: [
+                    {
+                        field: "User Graph",
+                        headerName: "User",
+                        cellRenderer: params => params.value ? "✅" : "",
+                    },
+                    {
+                        field: "Item Graph",
+                        headerName: "Item",
+                        cellRenderer: params => params.value ? "✅" : "",
+                    },
+                ]
+            },
+            {
+                field: "Sentiment",
+                headerName: "Sentiment",
+                cellRenderer: params => params.value ? "✅" : "",
+            },
+            {
+                field: "Review Text",
+                headerName: "Review Text",
+                cellRenderer: params => params.value ? "✅" : "",
+            },
+        ],
+        defaultColDef: {
+            flex: 1,
+            filter: true,
+            // floatingFilter: true,
+        },
+        pagination: true,
+        paginationAutoPageSize: true
+    };
+    // Create Grid: Create new grid within the #myGrid div, using the Grid Options object
+    modalityGridApi = agGrid.createGrid(document.querySelector("#modalityGrid"), modalityGridOptions);
+</script>
+
+<style>
+    /* Make h2 bigger */
+    .bd-page-width {
+        width: 100%;
+    }
+    .bd-main .bd-content .bd-article-container {
+        max-width: 100%;  /* default is 60em */
+    }
+
+    .ag-theme-quartz-auto-dark {
+        /* add border between cell columns */
+        --ag-cell-horizontal-border: solid rgb(230, 230, 230);
+    }
+</style>
+
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 001622f6..9f2eae28 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -100,6 +100,16 @@ html_theme_options = {
     },
     "pygment_light_style": "default",
     "pygment_dark_style": "github-dark",
+    "secondary_sidebar_items": {
+        "**": ["page-toc", "sourcelink"],
+        "index": [],
+        "models/index": [],
+    }
+}
+
+html_sidebars = {
+    "models/index": [],
+    "index": [],
 }
 
 # -- Options for intersphinx extension ---------------------------------------
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 15e0729b..a49e4b52 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -114,4 +114,12 @@ Quick Links
          :expand:
          :click-parent:
 
-         Contributor's Guide
\ No newline at end of file
+         Contributor's Guide
+
+.. raw:: html
+
+    <style>
+      .bd-main .bd-content .bd-article-container {
+        max-width: 100%;
+      }
+    </style>
diff --git a/docs/source/models/index.rst b/docs/source/models/index.rst
index a5e2ce2a..63cef157 100644
--- a/docs/source/models/index.rst
+++ b/docs/source/models/index.rst
@@ -5,4 +5,7 @@ Below shows a list of models available in Cornac.
 Clicking on the model name will take you to the model's API documentation.
 
 .. raw:: html
-   :file: ../_static/models/models.html
\ No newline at end of file
+   :file: ../_static/models/models.html
+
+.. raw:: html
+   :file: ../_static/models/models_modalities.html
-- 
GitLab