├── Canvas file features.ipynb ├── Graph with attachment files.ipynb ├── LICENSE ├── README.md ├── environment.yml ├── img ├── demo-vault-canvas-graph-example.png ├── demo-vault-networkx-graph.png ├── demo-vault_obsidian-app-actual-graph.png └── demo-vault_pyvis-graph-includes-attachments.png ├── obsidiantools in 15 minutes.ipynb ├── requirements.txt └── vault-stub ├── Crazy wall 2.canvas ├── Crazy wall.canvas ├── Isolated note.md ├── Sussudio.md └── lipsum ├── Alimenta.md ├── Brevissimus moenia.md ├── Causam mihi.md ├── Isolated note.md ├── Ne fuit.md └── Vulnera ubera.md /Canvas file features.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "485c35f2", 6 | "metadata": {}, 7 | "source": [ 8 | "**obsidiantools in 15 minutes**" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "a4dd8e34", 14 | "metadata": {}, 15 | "source": [ 16 | "# Libraries and config" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "id": "7f59b557", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# built-in libs\n", 27 | "import os\n", 28 | "from pathlib import Path\n", 29 | "\n", 30 | "# obsidiantools requirements\n", 31 | "import numpy as np\n", 32 | "import pandas as pd\n", 33 | "import networkx as nx\n", 34 | "\n", 35 | "# extra libs for this notebook (visualise graph)\n", 36 | "import matplotlib.pyplot as plt\n", 37 | "%matplotlib inline" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 2, 43 | "id": "efcf891d", 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | "Name: obsidiantools\r\n", 51 | "Version: 0.10.0\r\n", 52 | "Summary: Obsidian Tools - a Python interface for Obsidian.md vaults\r\n", 53 | "Home-page: https://github.com/mfarragher/obsidiantools\r\n", 54 | "Author: Mark Farragher\r\n", 55 | "Author-email: \r\n", 56 | "License: BSD\r\n", 57 | "Location: /home/mark/miniconda3/envs/obsidian/lib/python3.11/site-packages\r\n", 58 | "Requires: beautifulsoup4, bleach, html2text, lxml, markdown, networkx, numpy, pandas, pymdown-extensions, python-frontmatter\r\n", 59 | "Required-by: \r\n" 60 | ] 61 | } 62 | ], 63 | "source": [ 64 | "!pip show obsidiantools" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "id": "8cd600fe", 70 | "metadata": {}, 71 | "source": [ 72 | "## Vault directory" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 3, 78 | "id": "cb3495be", 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "VAULT_DIR = Path(os.getcwd()) / 'vault-stub'" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 4, 88 | "id": "85f65a04", 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "data": { 93 | "text/plain": [ 94 | "True" 95 | ] 96 | }, 97 | "execution_count": 4, 98 | "metadata": {}, 99 | "output_type": "execute_result" 100 | } 101 | ], 102 | "source": [ 103 | "VAULT_DIR.exists()" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "id": "93b2b3d9", 109 | "metadata": {}, 110 | "source": [ 111 | "## Obsidian tools" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 5, 117 | "id": "e0e10433", 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "import obsidiantools.api as otools # api shorthand" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "id": "c7f15b1b", 127 | "metadata": {}, 128 | "source": [ 129 | "# Canvas files" 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "id": "86bc90c5", 135 | "metadata": {}, 136 | "source": [ 137 | "Use the `connect` method to get the info on your canvas files." 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 6, 143 | "id": "d0dfef9a", 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [ 147 | "vault = otools.Vault(VAULT_DIR).connect()" 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "id": "266650ba", 153 | "metadata": {}, 154 | "source": [ 155 | "obsidiantools has `Vault` attributes for canvas files. The keys of these indices will always carry the `.canvas` file extension, to reflect how the links for canvas files appear in Obsidian.\n", 156 | "\n", 157 | "These are the attributes for canvas files:\n", 158 | "- `canvas_file_index`: index of canvas files where each value is a relative path to the file (the equivalent of `file_index` for canvas files)\n", 159 | "- `canvas_content_index`: index of canvas files where each value is a Python dict that represents the JSON content of a canvas file.\n", 160 | "- `canvas_graph_detail_index`: index of canvas files where each value is a tuple of information that can be used to recreate the layout of a canvas file in Obsidian.\n", 161 | " - The first item in the tuple is the graph itself.\n", 162 | " - The other two items contain the co-ordinates of nodes and the information about the graph edges.\n", 163 | " - See a recipe further down for how to visualise a canvas file. It will not show the 'group' in the visualisation, but the nodes will be in the expected layout." 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "id": "a37e0d56", 169 | "metadata": {}, 170 | "source": [ 171 | "## Filepaths for canvas files" 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "id": "702cf580", 177 | "metadata": {}, 178 | "source": [ 179 | "Get the filepaths of canvas files in the vault:" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 7, 185 | "id": "427e2edf", 186 | "metadata": {}, 187 | "outputs": [ 188 | { 189 | "data": { 190 | "text/plain": [ 191 | "{'Crazy wall 2.canvas': PosixPath('Crazy wall 2.canvas'),\n", 192 | " 'Crazy wall.canvas': PosixPath('Crazy wall.canvas')}" 193 | ] 194 | }, 195 | "execution_count": 7, 196 | "metadata": {}, 197 | "output_type": "execute_result" 198 | } 199 | ], 200 | "source": [ 201 | "vault.canvas_file_index" 202 | ] 203 | }, 204 | { 205 | "cell_type": "markdown", 206 | "id": "7a06bca7", 207 | "metadata": {}, 208 | "source": [ 209 | "## Content from canvas files" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "id": "500aa8ec", 215 | "metadata": {}, 216 | "source": [ 217 | "Get the content from the `Crazy wall 2.canvas` file:" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 8, 223 | "id": "b7ba2a92", 224 | "metadata": {}, 225 | "outputs": [ 226 | { 227 | "data": { 228 | "text/plain": [ 229 | "{'nodes': [{'id': '7ee7e59e29a5b091',\n", 230 | " 'x': -125,\n", 231 | " 'y': -30,\n", 232 | " 'width': 250,\n", 233 | " 'height': 60,\n", 234 | " 'type': 'text',\n", 235 | " 'text': \"Now we're getting meta...\"}],\n", 236 | " 'edges': []}" 237 | ] 238 | }, 239 | "execution_count": 8, 240 | "metadata": {}, 241 | "output_type": "execute_result" 242 | } 243 | ], 244 | "source": [ 245 | "vault.canvas_content_index.get('Crazy wall 2.canvas')" 246 | ] 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "id": "2ea77624", 251 | "metadata": {}, 252 | "source": [ 253 | "## Represent canvas file in a graph" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 9, 259 | "id": "0b3df04b", 260 | "metadata": {}, 261 | "outputs": [], 262 | "source": [ 263 | "import matplotlib.pyplot as plt\n", 264 | "# if using jupyter notebook:\n", 265 | "%matplotlib inline" 266 | ] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "id": "e0748b2d", 271 | "metadata": {}, 272 | "source": [ 273 | "Function using `canvas_graph_detail_index`:" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 10, 279 | "id": "55dbd910", 280 | "metadata": {}, 281 | "outputs": [], 282 | "source": [ 283 | "def plot_canvas_graph(vault, *, canvas_file, ax=None):\n", 284 | " \"\"\"Note: canvas_file includes .canvas\"\"\"\n", 285 | " G, pos, edge_labels = vault.canvas_graph_detail_index.get(\n", 286 | " canvas_file)\n", 287 | " if ax is None:\n", 288 | " ax = plt.gca()\n", 289 | " fig = nx.draw(G, pos, with_labels=True, ax=ax)\n", 290 | " fig = nx.draw_networkx_edge_labels(\n", 291 | " G, pos, edge_labels=edge_labels, ax=ax)\n", 292 | " ax.set_title(f'{canvas_file} graph')\n", 293 | " return fig" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "id": "6162d158", 299 | "metadata": {}, 300 | "source": [ 301 | "Plot graph for a file:" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 11, 307 | "id": "6f0d86a3", 308 | "metadata": {}, 309 | "outputs": [ 310 | { 311 | "data": { 312 | "image/png": "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yZMnD23btuXMGePvw3379qX5f/zw4cMm2//zzz+pV68e9vb2ODk50apVK65cuZJqrNeuXaNHjx54enpiZWVFnjx5aNmypcn38uNjm7n5y8dcm9SCaxOaoo97ysMDS7k2oanp54eWRtvQPYzg2oSm9Pt6LNfvxzwfgomnT58ycOBAPD09sba2pkyZMql+l6X3XVqkSJEXbudZmfIMxNmzZ6lWrRqFCxdm2rRpuLq68ttvvzF27Fj++OMPwx/M7NmzmTNnDj/99BPly5fH3t4egP3799OoUSOaNGnCxo0biYyM5KuvvqJu3bocO3YMKysrAKKjo3F0dGTEiBF4eXmRkJDAtm3b6N+/PydOnGDevHmGmEaNGkWdOnUYP348efLk4fz583z77bds3LiR48ePkzt3bkPdQYMGceTIERYsWIC7uzseHh48evSIGjVqkJCQwKRJk/Dw8GD58uX07NmTR48e8fnnn6d5PIatP4UujftQcddOErl6DFb5iuHcoC/mto7oHt8lIeKySd37O2by9NQeHCs2x6V2d4rmtqNRnkSjBCvluHzyySf4+vpibW3NsWPHGDduHNu2beP48eNYWlpm8DeZbOfOnWzdupUuXbpQsWJFdDodK1eupG3btowZM4aRI0ca6s6aNcvw6s8UMTExNGzYkPLly+Pu7v5S235W//79+fDDD43KChV6e7vlhHiXTJ06lVKlStGsWTMWLFiQbt3evXuzcOFCBg0axPfff49Op+PUqVMm30UffPABx44dY/To0VSoUIEbN24wduxYqlatyqlTp/D29jaqP378eOrUqWNUVqJECaOfz507R+3atSlTpgyrVq0iLi6OkSNH8t5773HixAly5cplqHv69Glq165NgQIFmDx5Mnnz5uX27dvs2LHD6Hs5IeIKD3bPwb50fexK1EVjZo7G8p83Fbq1G4OZld0/QaTxWmO9Ugxbf4rFH1VO9/i1atWK0NBQJkyYgJ+fH8uWLaNjx47o9Xqj77iQkBCTdY8cOcLAgQNp2bKlybJ0qUzwzTffKEBdunTJqPyTTz5RgLp//75SSqmePXsqGxsbk/UrVqyoihUrphITEw1lBw8eVICaNWvWC7ffrl07pdVqVVxcnKEsIiLCpF5oaKgC1LfffmtU7uvrqxo1amRU9v333ytAHTt2zKi8fv36ys7OTj148CDVWC7ceay8h25J9ZNv8Bplbu+sbApWVF5fbU6znvfQLSpXq+Rj6tr8K6PyixGPX3g8lFJq1qxZClB79uzJUP1n3b17V+n1epPyJk2aKFtbW6PjnJqFCxcqQM2bN8+oHFB9+/Z94favXr2qAPXDDz+8XOBCiAxLSkoy/NvOzk5169Yt1Xrr169XgFq5cmW67V28eFEBavjw4Ublhw4dUoCaMmWKoSw4OFgBavXq1S+Ms23btsrV1VU9evTIUBYWFqYsLCzUl19+aSjT6/WqTJkyqkyZMibfUc9/L7t8MFgByr3rj0blOap3VIDK+9nSdL+f83w6XwHKqU6PF34vb926VQFq2bJlRuX+/v7K09NT6XS6dPe/e/fuSqPRqIsXL77wWD0rU24TpLzZKUeOHEblTk5OmJmZYWlpiUajYd68ecTGxhq6PRYuXMjNmzcJDQ2lS5cuaLX/dGxUq1YNPz8/1q9f/8Lt58qVCzMzM8zNzQ1lbm5uJvXKly+Pubk5169fB/7pqrp06RJBQUGGuMLCwjh48CC5c+emfPnyRm00bdqU6Ohotm/fbig7duwYHTp0wMfHh2Jeubg5uwd3N05C98j4NkfMuYMkPb2PY+VWaNLINFM8PrYJ8xy5sSv6nqHM3EzDksPG96iUUuzevZs6deowffp0o2MCGB1TgIsXL/Lhhx/i5uaGlZUVRYsWZebMmUZ1XF1dU42vUqVKxMTEcP/+/XRjnz9/Pvb29rRv3z7V5XPmzMHPzw8rKyuKFSsmXf9CvAbnzp2jY8eO5M6dGysrK7y8vOjatSvx8fFAxufcnz59Oj4+PrRr1y7deumdBwCsra1fcg9Ap9OxZcsWWrdujaOjo6Hc29ubOnXqGJ0ffvvtN06cOMHAgQMNvckplh4Jx9ws+TvtztKhRG3+Mfnfvw7m2oSm3Nsy9aVjA0DpeRyykvLF/bC2tqZChQrs2bPHqMr69euxt7enbdu2RuUBAQHcunWLI0eOpNn8kydPWL16NbVq1cLX1/elQsuUZKBbt244OTnRu3dvrly5wpMnT9iyZQtz5syhb9++2NnZERISQuPGjbGxsSEkJISQkBCaNGnC6dOnAShVqpRJu6VKlTIsf5ZSCp1Ox4MHD1i5ciULFy5k8ODBJie+5+3fv5+kpCSKFy8OQLly5QgJCcHd3Z3q1asb4vLw8CAhIcHkDwowlJ08edJQFhYWZrhFUqzHBJxqdyfp6X1uLxpEUswjQ72468n7ovR67iz5kmuTWnB9avvkxOFJ1D/7p08i/uY5LHMX4PHR9dyYFcC1ic0In9mDX//3E0opQxJQrVo1/P392bdvH4cOHSI6OpqDBw8yYsQIatSoQfXq1Q3tnj17looVK3L69Gl+/PFHtmzZQpMmTfjss88YM2ZMuscOIDg4mFy5cqWaaKW4ePEiBw4coEOHDobbQM/atGkTM2bMYOzYsaxZswZvb286duyY6niECRMmYGlpia2tLTVq1GDTpk0vjFEIAX/99RcVK1bk8OHDjB07lqCgIL7//nvi4+NJSEjIcDs6nY6QkBDKli3LlClT8Pb2xtzc3NANr555eM3b25vmzZszdepUgoODefr0KefOneOzzz7Dy8uLDh06mLTft29ftFotjo6ONGjQgN9//91o+eXLl4mNjU3z/HDp0iXi4uKA5GQAwMHBgcaNG2NtbY29vT1NmzZl64FjhkcInRv0IUe15AsVl8YDce8ymRzVjWO7Pb8f1yY24/qMztzb/KPJhV2KJ39uJebyH+Rt/ClLlizBzMyMRo0aGXX3nz59mqJFi5qcn1L2KbVzXIoVK1YQHR1Nz54906yTlkwZM+Dj40NISAgtW7akYMGChvLPPvuMadOmAVClShXDFXyVKlUMdaKikk+Czs7OJu06Ozsblj9r4sSJfP3110DygIthw4bx3XffpRvjkydP6NOnD/ny5aNHjx4AODo6UqVKFaysrHBycjKKq1ixYuzevZvw8HC8vP55njTlj/XZuNq0aUObNm14Gq9j0JEd2DoWwKZgJW781Jnos/txrNAMgKT/P+HfWz8e+zINcXqvM4n3b/Lwt8VELBuKR4+fMLOwRh/zGJISibv2Fwm3L+JUswvmDq7EnP+dq1vn0KxFBDfCwzhx4oQhu9doNKxatYpVq1YByQP7pk2bRlhYmCHOTz/9FBsbG3799VccHJJn0urduzeRkZF8//33fPDBByZZfYqVK1eyb98+RowYYdTm8yZPngxAgwYNuHzZdBzE3bt3Wb16Na6urkDyVUfjxo0ZMmQIZcuWBZJfJNK+fXuqV6+Om5sbt27d4tdff6V58+aMGzcuzR4HIUSy3r17Y2ZmxsqVK3FxcQGST9ZVqlQhMjLSZHC2UoonT56Y/J+9e/cu8fHx7Nq1i5CQEAYPHoy7uztBQUF88cUXXLlyhcGDBxvqT5gwgdGjR/P+++8byooUKcKvv/7K/fv3Db2Kjx8/pnv37lSuXBknJyeuXbvG3LlzqV27NnPnzqVmzZrAPxddiYmJJrGlXBQdP34cNzc3/v77byD54rRRo0bMnTuXyMhIpk6bxu29B/D46Ge09s5YunqR4OQBgEUub6w8/hmHpM3pgVPNrljmLoBGa0n87Qs8PryW2LDjeHSfhtbB1fhA65PI3eE7YrSWNPqgAQ0aNMDHx4eRI0eya9cuIPlcUaBAAZPfUco5L7VzXIr58+fj5ORE69at06yTppe6qfCKXL16Vfn6+qrq1aurNWvWqP3796tJkyYpR0dH1aNHD0O9bt26KTs7O6N1ly5dqgB1+PBhk3Y/+eQTZWVlZVJ++/ZtFRoaqnbs2KG++uorZWlpqfr165dmfLGxsapevXrK1tY21e14e3urJk2aGJWdPXtWWVlZqRo1aqjTp0+re/fuqZ9//llZWloqQH366aeGuk+ePFFffvmlyueTX6ExU4DhY1+2keE+k7VP2eSyMg2fGx8wXAHKuVH/5PtRfRcZ1nfvMtmork2hKgo0RtuQj3zkIx/5pP6xcMmrAOVYrf0/YwYaD1SAcu82Nd2xAd5Dtyj3rj8qNGbKofwHJmMGHMo1NZSdvvnQcJ6ztLQ0jAUoVKiQatiwocl559atWwpQ33//farnrdOnTyvI2Dir1GRKz8DQoUN5/PgxJ06cwM4ueQRmzZo1cXV1pUePHnTt2pVatWqlum5K1ppadnT//v1Uewzc3d0No9Tr169Pzpw5GTp0KD169DBcXaaIj4+nZcuW/P7772zZsoXKldMf9ZmiaNGirF+/nl69ehlGt+bLl48ff/yR/v37kydPHkPdDz/8kD179vBR/yGsvGaJmZUtoCFy9WhU4j9dcmY2yVfjNvnLGW3LpkA5QEPCnctQGsys7QENGisbrPIYP05iU7ACsRcP4+TkxMOHD/9p28yMWrVqGV67+ffff9O3b1969+5N27ZtuXv37guvqIcOHUr9+vWNykJDQxkxYgTlypVjzJgxhvuCqUm5PdGnTx/atGljsvz999839AI8a9OmTUybNo25c+ca9Sw9b/ny5cydO5fAwECTUclCiGQp/9cDAgLo0qVLhtZp3LgxtWrV4quvvjIqj4+Pp3Hjxtja2rJ582ajZVu2bGHKlCnMnDmTokWLcvToUYYOHcqoUaOMvu+fPn1Kx44dqVGjhkn7z5s6dSqbN28mKCgIKysrwsPD6d69OwMGDKB58+ZGdX/55RdWr15NUFAQlpaWzJ07l+XLlxu+81JE6Gzo3KoJCXcuZehYPM/KszBaZ0/ib503WWZu/8+LjhJ0eiD5/JSQkMDTp0/JkSMHLi4uaZ7fIPVeccDwGPu/uUUAmXSb4MSJExQrVsyQCKRIeQXk6dOn00wGUk60p06donHjxkbLTp06ZfKYSWoqVaoEJD8f/2wyEB8fT4sWLQgODmbjxo3UrVs34zsFNGrUiGvXrnHp0iV0Oh1+fn6GbviUbqxHjx6xZcsWRo0aRZuPB7Lpp+TbCEqXiD72iVF7lm4+xPz9W5rbSxm0Z2ZhhdbZk6ToB6aV/v8eXVBQEGfPnmX06NFcv34dvV5P7ty5DY/p1KxZk/79+6OUok6dOsTExGBubk6XLl3o27dvqtvPnz+/ITkD2LFjh+ERzY0bN6Y6huJZ06ZNw9LSkrFjxxq18ywzMzOTR4n2798PQMOGDcmbN2+a7acMtKlatSqFCxdONxYhsqvY2FjMzc2xsLAw+b+WFnNzc9zd3VOtX6hQIe7cuWOy7MKF5Ml7KlWqRIUKFQz/PwMCAkyS9SJFihAVFfXCeFauXAkk3+a0trZGp9PRu3dv4uPjTdadOHEivr6+NGjQAIA7d+6wfPlyChUqZFT3zK1HoBQazX8YUqdI9fHCpKf/fEdbas0McVhaWhrGTJUsWZLly5ej0+mMxg2cOnUKMH2UEpLn5Fm8eDHly5c3mo/nZWTKAEJPT0/OnDnD06dPjcpTBlGk9wWfJ08eKlWqxJIlS0hKSjKUHz58mPPnz9OqVasXbj84OBjAaLRlSo/A3r17Wbt2reEP5mVpNBoKFSpE0aJFSUpKYvr06ZQpU8aQDGg0GpRSWFlZ4eNiR8qfy9O/doDSG7Vl61cV0BB75Q+j8tjLxwCFpec/vQC2hauh4mOIu/G3SV17e3tKly5Njx49uHz5MvPnzyd//vxG+79//370er2hzNbWljp16nD8+HFKlSpFhQoVTD7PnsB37txJixYtqFGjBhs2bHhhInDnzh22bdtGixYt0kwEAPbs2UNERITh56SkJFauXEnBggXT/TtJTExk5cqVuLq6vvSoWiGyExsbG2rVqsXq1av/9cRjz2rdujWPHz/m0KFDRuXbtm3D3t7eMCDb09MTwGTSoKioKC5cuJDu/2+ABw8esGXLFsqUKWN48kCr1fLBBx+wbt06njz55+IqPDyc4OBgo/NDo0aNsLW1JSgoyKjdh+HnSYp+gKXnv7uAiL95Dt2DW1h5mk76E3PhEEqXgAbwcbHjyZMnbN68mffee8/wdFvLli15+vQpa9euNVp30aJFeHp6ptpbvWnTJu7du8dHH330r2KGTOoZGDhwIC1atMDf359Bgwbh6urK4cOH+f777ylWrBiNGjVKd/2JEyfi7+9P27Zt6dOnD5GRkQwdOpQSJUoQEBBgqDdq1CgiIiKoWbMmefLk4eHDh2zfvp25c+fStm1bo8cA27RpQ1BQEN988w0uLi5Gf6COjo4UK1bshfvVv39/ateujYuLC1euXGHGjBncuHHDcCWb0lbNmjX54YcfcHV1xSHqIeFnjvH05C7jSSsAC5d8OJRrwpPj29BY2mBTsAK6/x9AaJm7IHZFa/zTbqVWRJ/Zx70N3+P0XmfMHV2JOXeQ2EtHmDx5MjY2yRNk7Nixg40bN/LNN9/g7e1NUFAQx44dY9q0afj6+hp1MU2fPp0aNWrw3nvv0bt3b3x8fHjy5AmXLl1i8+bN7N27F0geJNmiRQvc3d0ZNmwYJ06cMNqPYsWKGT3mA8l/2Dqd7oVdWq6urrz//vuMGDECOzs7Zs2axblz54weL/z8889JTEykevXquLu7c/36dX766SdOnDhBYGCg0SOkQghTU6ZMoUaNGlSuXJmhQ4fi6+tLREQEmzZtYs6cOTg4OLB//37u3r0LJCfl165dMzzVU6tWLcPjyUOGDGHp0qW0bduWb7/9lrx587JmzRo2bdpk9F3UqlUrRo4cSe/evblx4wblypXj9u3b/PDDD8TExDBgwABDfB9++CFeXl5UqFABV1dXLl68yI8//khERAQLFy402pcxY8ZQsWJFmjZtytChQw2TDrm6uhoNXnRycmLs2LEMGTKE7t2707FjR+7cucOIESOwcnLDoVyTFx63W/P7YVeiDhYu+dBoLUm4dYHHR9ZibueEY5VUBvGZmROxYjgF32/P9i1xTJw4kcePHxs9ndWoUSP8/f3p3bs3jx8/xtfXl+XLl7N9+3aWLFmS6vfZ/PnzsbGxMZl07aX8q5EGr8DevXtV/fr1lbu7u7KxsVF+fn5q8ODB6t69e4Y6qQ0gTLFz505VpUoVZW1trZydnVXXrl1NJg7atGmTqlevnsqdO7fSarXK3t5eVapUSc2YMcNowiKlVLoDSmrVqmVUN7UBhEop1bx5c+Xh4aEsLCyUu7u76t69uwoLCzOpd+PGDdW6dWuVM2dOZWljp2wKlFceH81U5o5uyq5EXaPBKF5fblROtbsrbU4PhZlWmds7K/uyjVW+gStMJ7boE6hsi9ZUZtb2CnOtsnTLr5r1N54w6e+//1Zt2rRR3t7eytraWllbW6siRYqoL774QkVFRZnEevXqVdWjRw+VJ08eZWFhoXLlyqWqVaumvvvuO0OdUaNGpXv8goODTdr18/NTPj4+qU5W9OzvpG/fvmrWrFmqYMGCysLCQhUpUkQtXbrUqN78+fNVpUqVlLOzs9JqtSpnzpyqQYMGaseOHWm2LYQwdvbsWdW2bVvl4uKiLC0tlZeXl+revbthQp5atWpl+P94eHi46tChQ/J3nKWlKlWqlFqwYIHJNm/fvq369eunfH19lbW1tfL09FRNmjRRISEhRvW+//57VaZMGZUjRw5lbm6ucuXKpVq2bKmOHj2a6r4cO3ZM1a1bV9na2ipHR0fVokULk0nuUsydO1eVKFFCWVpaKhcXF9WpUyc1aP5uVWDY1hcOILQtWlNpc3oojYV18vezo5uyL9tI5en3a+qTDtXurnK+10k5uuRWlpaWqmzZsql+Tz158kR99tlnyt3d3XD8li9fnmr84eHhyszMTHXt2jXV5Rklby3MZBcjnuA/Le1xAf/V7kE18XVzeG3tCyFEVpMdv5flrYWZrFBuB97zdTXMdvWqmJtpeM/X9a37gxNCiLdddvxelmTgLTC+ZUm0r/iPTmumYXzLkq+0TSGEyC6y2/eyJANvgXzOtoxpVvyVtjm2WXHyOdu+0jaFECK7yG7fy5IMvCU6VPRiSH2/V9LWF/UL076i14srCiGESFN2+l6WAYRvmRWh4YzadAadXhlelJER5mYatGYaxjYr/lb/wQkhxLsmO3wvSzLwFrp+P4Zh609x4NI9zM006f7xpSx/z9eV8S1LvrVdUEII8a7S6/W06voJ192rE2XhliW/lyUZeItdjHjC0iPhBF+IJDwqhmd/URrAy8WWOn5udK7i9VaOThVCiHfd48ePad++Pdu3b8fLy4vdR09nye9lSQbeEdHxOsKioknQ6bHUmuHjYoedVaZMICmEENnC5cuXadKkCRcuXEApRYkSJQzvCICs9b38bkadDdlZaSnumSOzwxBCiGxh7969tGrViujoaFKumePj443qZKXvZUkGhBBCiGfs378ff39/lFI823keHR2diVG9XvJooRBCCPGMPHnyULZsWZ6/ix4bG5tJEb1+kgwIIYQQz/D19SU0NJQ5c+YYlWflZEBuEwghhBDP0Wg07N69Gz8/P7Zs2cKMGTOIiIjI7LBeG3maQAghhHjO1atX8fX1ZebMmXz66aeZHc5rJ7cJhBBCiOfMmDGDnDlz0rVr18wO5Y2QZEAIIYR4xsOHD5k3bx69e/fG1vbtnz3wVZBkQAghhHjGvHnzSEhIoG/fvpkdyhsjYwaEEEKI/5eYmEiBAgXw9/dnwYIFmR3OGyM9A0IIIcT/W7NmDTdu3GDQoEGZHcobJT0DQgghBKCUomLFiri4uLBjx47MDueNknkGhBBCCODAgQP88ccfbN++PbNDeeOkZ0AIIYQAmjdvzuXLlzl16hQajSazw3mjpGdACCFEtnfhwgU2b97MvHnzsl0iADKAUAghhGDatGm4ubnRqVOnzA4lU0gyIIQQIluLiopi4cKF9O3bFysrq8wOJ1NIMiCEECJb++WXX1BK0bt378wOJdPIAEIhhBDZVnx8PD4+PjRv3pxffvkls8PJNNIzIIQQIttavnw5d+7cYeDAgZkdSqaSngEhhBDZklKK0qVL4+3tzebNmzM7nEwljxYKIYTIlnbv3s2pU6eYPn16ZoeS6aRnQAghRLbUqFEjIiIi+OOPP7Ll3ALPkp4BIYQQ2c6ZM2fYvn07ixcvzvaJAEjPgBBCiGyoZ8+ebN++nStXrmBpaZnZ4WQ6eZpACCFEthIREcHixYvp37+/JAL/T5IBIYQQ2cqsWbOwsLDgk08+yexQ3hqSDAghhMg2YmNjmTVrFj169CBnzpyZHc5bQ5IBIYQQ2cbixYuJiorK9pMMPU8GEAohhMgW9Ho9xYoVo3jx4qxduzazw3mryKOFQgghsoWgoCDOnz/PggULMjuUt470DAghhMgW3n//fWJiYggJCZG5BZ4jPQNCCCGyvOPHjxMcHMzKlSslEUiF9AwIIYTI8rp06cKBAwe4dOkSWq1cBz9PniYQQgiRpd28eZMVK1YwcOBASQTSIMmAEEKILO2nn37C1taWHj16ZHYoby1JBoQQQmRZT58+Zc6cOXzyySc4OjpmdjhvLUkGhBBCZFmBgYE8efKE/v37Z3YobzUZQCiEECJLSkpKws/Pj8qVK7Ns2bLMDuetJiMphBBCZEkbN27kypUrrFy5MrNDeetJz4AQQogsqUaNGpibm7N///7MDuWtJz0DQgghspwjR45w8OBBNmzYkNmhvBOkZ0AIIUSW0759e/7880/Onz+PmZmMlX8R6RkQQgiRpYSFhbFmzRp++uknSQQySI6SEEKILGXGjBk4OTnRrVu3zA7lnSHJgBBCiCzj0aNHzJs3j08//RQ7O7vMDuedIcmAEEKILGPevHnExcXRr1+/zA7lnSIDCIUQQmQJiYmJFCxYkPfff5+FCxdmdjjvFOkZEEIIkSWsWbOG69ev8/nnn2d2KO8c6RkQQgjxzlNKUalSJZycnNi1a1dmh/POkUcLhRBCvPMOHDjAsWPHCAoKyuxQ3knSMyCEEOKd16JFCy5evMjp06fRaDSZHc47R3oGhBBCvNMuXrzIpk2bmDt3riQC/5IMIBRCCPFOmzZtGrly5aJTp06ZHco7S5IBIYQQ76yoqCgCAwPp27cv1tbWmR3OO0uSASGEEO+sOXPmoJSid+/emR3KO00GEAohhHgnxcfH4+PjQ7NmzZgzZ05mh/NOk54BIYQQ76QVK1Zw584dBg0alNmhvPOkZ0AIIcQ7RylF6dKl8fLyYsuWLZkdzjtPHi0UQgjxztmzZw+nTp1i2rRpmR1KliA9A0IIId45jRo14s6dO/z5558yt8ArID0DQggh3ilnzpxh+/bt/Prrr5IIvCLSMyCEEOKd0rNnT4KCgrh69SqWlpaZHU6WIE8TCCGEeGdERESwZMkS+vfvL4nAKyTJgBBCiHfGrFmzMDc3p1evXpkdSpYiYwaEEEK8VaLjdYRFRZOg02OpNcPHxQ47Ky2xsbHMmjWLHj16kDNnzswOM0uRZEAIIUSmuxjxhKVHwgk+H0n4/RieHcymAbycbXFLussjbBkwYEBmhZllyQBCIYQQmeb6/RiGrT/FgUv3MDfTkKRP+5RkhkKPhvd8XRnfsiT5nG3fYKRZmyQDQgghMsWK0HBGbTqDTq/STQKeZ26mQWumYUyz4nSo6PUaI8w+JBkQQgjxxv0cfJHJOy/853aG1PejX51CryCi7E2eJhBCCPFGrQgNfyWJAMDknRdYGRr+StrKziQZEEII8cZcvx/DqE1nXmmbIzed4fr9mFfaZnYjyYAQQrwm+/btQ6PRpPo5fPiwoZ6Pjw9NmzbNcLs//fQTRYoUwcrKivz58zNmzBgSExPTXWf48OFoNBpKlChhsuz+/ft06NABNzc3NBoNLVq0ICwsDI1Gw+TJkzMU09GjR2nQoAEODg7Y29tTp04dDh48aFJv2PpT6F5ifEB6Hh5YyrUJTYl/+pBh60+9kjaf1blzZzQajcnv5mWOzd69e+nRowdFihTBzs6OPHny0Lx5c/744w+Tukop5s6dS/ny5XF0dMTFxYVatWqxdetWo3oXLlxgyJAhlC9fHicnJ5ydnalevTpr1qz51/sqyYAQQrxm48ePJyQkxOiT2kk5I8aNG8eAAQNo1aoVO3bsoE+fPowfP56+ffumuc6JEyeYPHkyuXPnTnX5t99+y/r165k6dSohISFMmjTppWIKDQ2lZs2axMbGsnjxYhYvXkxcXBx169YlJCTEUO9ixBMOXLr3UoMFMyJJrzhw6R6XIp+8sja3bt3Khg0bcHR0/E/tzJ49m7CwMAYMGMC2bduYPn06kZGRVKlShb179xrVHTVqFJ988gmVKlVi7dq1LFy4ECsrK5o2bcq6desM9Xbu3MnWrVtp3bo1q1evZunSpRQqVIi2bdsyduzYfxWnzDMghBCvWaFChahSpcp/bicqKorvvvuOjz/+mPHjxwNQu3ZtEhMTGT58OAMHDqRYsWJG6+h0OgICAujVqxd//fUX9+7dM2n39OnTFCxYkE6dOhnKwsLCMhzXiBEjcHJyYvv27djaJj/uV69ePQoUKMCQIUMMPQRLj4S/8PHBf8vcTMOSw+GMblb8P7f16NEjevXqxbfffsv06dP/U1szZ87Ezc3NqKxhw4b4+voyfvx43n//fUP5ggULqFGjBrNnzzaU+fv74+7uzqJFi2jVqhUAHTp0oG/fvkYvaWrUqBH37t1j4sSJfPXVV1hZWb1UnNIzIIQQb4n169dTqlQprK2tKVCgADNmzDBavn37duLi4ggICDAqDwgIQCnFhg0bTNqcMGEC9+/fZ9y4cSbLUrq7d+/ezd9//224hbFv3z5DHb1ez7hx4/Dy8sLa2poKFSqwZ88eo3YOHjxI7dq1DYkAgIODAzVr1uTQoUPcvn0bgODzkSTpFdFn9nH718GE/9iG8B/bcGtBf578tdOwbuzV40Su+ZYbM7tx7YeW3PzlY6K2/0xSzKNUj1vS43vcXvMd37WrRI4cOejcuTN37941qbds2TKqVq2Kvb099vb2lClThvnz55vUGzx4MB4eHnz22Wepbu9ljs3ziQCAvb09xYoV4/r160blFhYW5MiRw6jM2tra8Enh6uqa6tsaK1WqRExMDPfv30837tRIMiCEEK9Z37590Wq1ODo60qBBA37//XeTOidOnGDgwIEMGjSI9evXU61aNQYMGGB0X/r06dMAlCxZ0mhdDw8PXF1dDctTnD17lu+++47Zs2djb29vsk0PDw9CQkIoW7YsBQoUMNzCKFeunKHOzz//zPbt25k2bRpLlizBzMyMRo0aGXX/JyQkpHolmlJ26tQpnsbrCL8fw8PflnBv82S09i64NBlIrlbfYF+iLkmPIg3r6R7exipPEZzr9yF3+2/JUb0D8bfOc2fJV6gkncl2IteNwyKnB64thjJs+Ag2bNhAgwYNjMZRjBw5kk6dOuHp6cnChQtZv3493bp149q1a0Zt7d69m19//ZV58+Zhbm5usq1nZeTYpObRo0f8+eefFC9u3IsxYMAAtm/fzvz583nw4AG3b9/m888/59GjRy9MTACCg4PJlStXqgnIi8htAiGEeE1y5MjBgAEDqF27Ni4uLly6dIkffviB2rVrs3XrVho0aGCoe+vWLY4fP07p0qWB5G7fyMhIvv32W/r06YOtrS1RUVFYWVlhZ2dnsi1nZ2eioqIMP+v1enr06EGrVq1o3LhxqvFZWVlRpUoVHB0dSUhIMLqVkXJ1mZSUxK5duwxXpg0aNMDHx4eRI0eya9cuAIoVK8bhw4fR6/WYmSVfY+p0Oo4cOQIk3964FhVNwsM7PApZhV3x2rh+MMSwLZv8ZY3icij7T7xKKazyFsXaqyQ3Z/cg9sof2BaqbFTftnBVctbpAUDTTjXIl8eTTp06sWrVKjp16sTVq1cZP348nTp1YsmSJYb1/P39jdp5+vQpH3/8MUOGDDH8HtKTkWOTmr59+xIdHc0333xjVD5w4EBsbGzo27cvPXv2BJJ/r5s3b6Z69erpxjJv3jz27dvH9OnTX5jEpEZ6BoQQ4jUpW7Ys06ZNo0WLFrz33nsEBARw6NAhPDw8+PLLL43qFi9e3OQE9OGHH/L48WP+/PNPQ1lq3cOpLZsyZQoXL15k2rRp/2kfWrVqZdRF7eDgwAcffMBvv/1GUlISAP379+fChQv069ePmzdvcv36dT799FPDVbeZmRkJOj1xYSdA6XEo1yTdbSZFPyRq+8/cmNmd8EnNCZ/UnJuzk0/2iVHXTerbFa9j+HeCTk+7du3QarUEBwcDsGvXLpKSktIdZAkwdOhQLCwsGDly5IsPDBk7Ns8bMWIES5cuZerUqZQvX95oWWBgIAMGDKBfv37s3r2bbdu2Ub9+fZo3b86OHTvSjCMoKIi+ffvSpk0b+vfvn6HYnyc9A0II8QY5OTnRtGlTfvnlF2JjY7GxsQHA3d3dpG5KWcoVv4uLC3FxccTExBjdn4fkK/mUk0t4eDgjR45kwoQJWFpa8vDhQyD5al2v1/Pw4UOsrKwM205PWnElJCTw9OlTcuTIQY8ePbh7967hlgRA1apVGTJkCBMnTiRPnjxYas3Q//89f3MH1zS3p5SeiJUjSHp6nxzVOmCZyxuNpTUoxZ1fB6MS403WMbdzMvzbUmuGVqvFxcXFcNxSxg/kzZs3ze0ePXqUWbNmsW7dOuLi4oiLiwOSe1h0Oh0PHz7ExsbG6HZIRo7Ns8aMGcP/tXe/MU2tdxzAv23ZaaF00FauwLxts4tsEYUSy8a8YrkvYCAbAWLccFuybJqYxcTFbFEbsO2t/4jB6KslJovoRXM1kplJllVfdMnEeTXZJAgGvREGvpC7st4A2oi9/PaC0NGVghrEJef7Sfqm59dzTh8Snm+f85znHD58GEeOHMGePXsStkUikfiIwPxLQ7W1taisrMTu3bsxNDSUdLxgMIimpiZUVVXhwoULi4bFxXBkgIhohc2tAj//H/fTp0+T6ubes1qtAP47V6Cvry+pLhwOx29XfPz4MaLRKPbu3Quz2Rx/9fT04MGDBzCbzTh48OArnWuq81IUJWEewv79+xEOh9HX14fh4WHcunULkUgERqMRGzduhMNqhC5jtnP8ajL5joY5L//1T7z8Ygjmj36Br7t+CIO9GPq8QmjTTSk/89WzLwHMPt3QYTUiFothfHw83m45OTkAgCdPnqTcx8DAAEQEjY2NCW02OjqKYDAIs9mcMMv/ddoGmA0CPp8PPp8PHo8n6XODg4OIRqMoKytL2uZyuTA8PIypqamE94PBIBoaGuB2u9HV1QVFUVJ+v6UwDBARraBIJILu7m44nc6EIeb+/n709vYm1F68eBEmkyk+oa+mpgYGgwEdHR0JdR0dHfHFggDA6XQiFAolvUpKSuBwOBAKhZJ+maYy90t5zuTkJK5du4aKioqka9N6vR7r16+H3W7HyMgILl26hF27diE9PR1GfRo+cG4CNFpM/v1PixxxNiBpdIkD11P/+HPKTzzrn70cYLNmwKhPw+XLlxGLxVBZWQkAqK6uhk6nS+rM56upqVmwzVavXo3y8nKEQiFs27btjdomEAjA5/OhpaUFXq93wePn5+cDQMJiVMBscLx9+zbMZnPCXJHr16+joaEBmzdvxtWrV1/7VsL/xcsERERvyY4dO2Cz2eByubBq1So8evQI7e3tGBsbS+rQ8/PzUV9fD5/Ph7y8PHR2duLGjRtoa2uLXxKwWCxoaWlBa2srLBYLqqurcffuXfh8PuzcuTO+xkB2dna8I5wvOzs7oZN8FTqdDlVVVdi3bx9mZmbQ1taGiYkJ+P3+eM39+/fR1dUFl8sFvV6P3t5eHD9+HGvXrkUgEIjX1X6vGA83bceXPZ9CYtMwrnNDo8/Ay/AoZqITyK74Cb5mXYO07DxE/nIOAKA1ZCL6+R1Eh++lPMfng3+DVpeGitrv49SpXrS2tqKkpATbt28HMLvCo8fjQSAQQDQaRXNzM7KysjAwMIBwOAy/34/c3NwFh/0NBgOsVuuCbfYqbdPe3o5Dhw6hpqYGdXV1SZ393KRNm82GpqYmnDlzBnq9Hlu3bsWLFy9w7tw59PT0IBAIxEeSbt68iYaGBuTm5sLj8eDevcS2Wbdu3esvliRERPRWHDt2TJxOp2RlZYlOp5OcnBxpbGyUO3fuJNTZ7Xapq6uTK1euSFFRkSiKIg6HQ06ePLngfk+fPi2FhYWiKIrYbDbxer0yPT295Pm43W4pKip6pfeHhoYEgLS1tYnf75c1a9aIoihSWloqwWAwoXZwcFC2bNkiFotFFEWRgoICaWlpkampqYS6h08nxH6gW6w/2CdK3lrRpCmiUdJFWf2BWLf+WuwHusV+oFvyd/5ODI5S0SjpojVkSsa3N8s3fnVWAEjWh83xuqwPmwWA5P78lKQXfEeMxkwxmUzS3NwsY2NjSd/z/PnzUlZWJgaDQTIzM6W0tFTOnj27aJvN/W3etG3cbrcASPmaLxqNyokTJ6S4uFhMJpNYLBYpLy+Xzs5OmZmZidd5vd5F9xkKhRb9TgvhI4yJiGjF/Oz3n+HW4/FlXYVQp9Vg0zet+OSX3126mBbEOQNERLRijjZuQJr2zWa8p5Km1eBo44alCyklhgEiIlox71sy4F+G5wfM93F9Ed63ZCxdSCkxDBAR0Yr6cZkNv6kuXJZ9/bb6W/hRmW1Z9qVmnDNARETvxKd3R+D9Yz9iM/Jacwh0Wg3StBp8XF/EILBMGAaIiOidGf33c3j+0Ie/fh5e8vHGc9srClbhaOMGXhpYRgwDRET0zj0am8SFz0YQevgFRsafY37HpMHsgkIfFb6Hn5bbUPBe6tUI6c0wDBAR0f+VZy9iGB5/hunYDJQ0LRxWI4x6rpH3NjEMEBERqRzvJiAiIlI5hgEiIiKVYxggIiJSOYYBIiIilWMYICIiUjmGASIiIpVjGCAiIlI5hgEiIiKVYxggIiJSOYYBIiIilWMYICIiUjmGASIiIpVjGCAiIlI5hgEiIiKVYxggIiJSOYYBIiIilWMYICIiUjmGASIiIpVjGCAiIlI5hgEiIiKVYxggIiJSOYYBIiIilWMYICIiUjmGASIiIpX7D4R8K+u/BR4vAAAAAElFTkSuQmCC\n", 313 | "text/plain": [ 314 | "
" 315 | ] 316 | }, 317 | "metadata": {}, 318 | "output_type": "display_data" 319 | } 320 | ], 321 | "source": [ 322 | "plot_canvas_graph(vault, canvas_file='Crazy wall.canvas')\n", 323 | "plt.show()" 324 | ] 325 | }, 326 | { 327 | "cell_type": "markdown", 328 | "id": "54c8a089", 329 | "metadata": {}, 330 | "source": [ 331 | "![Obsidian graph](/img/demo-vault-canvas-graph-example.png?raw=true \"Obsidian graph\")" 332 | ] 333 | } 334 | ], 335 | "metadata": { 336 | "kernelspec": { 337 | "display_name": "Python 3 (ipykernel)", 338 | "language": "python", 339 | "name": "python3" 340 | }, 341 | "language_info": { 342 | "codemirror_mode": { 343 | "name": "ipython", 344 | "version": 3 345 | }, 346 | "file_extension": ".py", 347 | "mimetype": "text/x-python", 348 | "name": "python", 349 | "nbconvert_exporter": "python", 350 | "pygments_lexer": "ipython3", 351 | "version": "3.11.0" 352 | }, 353 | "toc": { 354 | "base_numbering": 1, 355 | "nav_menu": {}, 356 | "number_sections": true, 357 | "sideBar": true, 358 | "skip_h1_title": false, 359 | "title_cell": "Table of Contents", 360 | "title_sidebar": "Contents", 361 | "toc_cell": false, 362 | "toc_position": {}, 363 | "toc_section_display": true, 364 | "toc_window_display": true 365 | } 366 | }, 367 | "nbformat": 4, 368 | "nbformat_minor": 5 369 | } 370 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Mark Farragher 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # obsidiantools demo 2 | This is a public repo for exploring the functionality of `obsidiantools` as a Binder project. 3 | 4 | ## obsidiantools in 15 minutes 5 | Check out the notebook through Binder on a pre-configured virtual machine. There is a basic Obsidian vault (set of 'lipsum' markdown files) configured on there to show the functionality of the API. 6 | 7 | ## wiki 8 | See the [wiki](https://github.com/mfarragher/obsidiantools/wiki) for more detail on `obsidiantools`. This also includes recipes of code. 9 | 10 | ## Notebooks 11 | |**Notebook**|**Info**| 12 | |---|---| 13 | |[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/mfarragher/obsidiantools-demo/HEAD?filepath=obsidiantools%20in%2015%20minutes.ipynb)|Launch the repo and explore notebooks interactively with Binder.| 14 | |[![nbviewer](https://img.shields.io/badge/render-nbviewer-orange.svg)](https://nbviewer.jupyter.org/github/mfarragher/obsidiantools-demo/blob/main/obsidiantools%20in%2015%20minutes.ipynb)|Launch the repo and see static notebook output in nbviewer| 15 | 16 | ### Dummy vault 17 | The dummy vault is the `vault-stub` directory. This is how the graph looks in NetworkX: 18 | 19 | ![NetworkX graph](/img/demo-vault-networkx-graph.png?raw=true "NetworkX graph") 20 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: python 3.10 2 | dependencies: 3 | - python=3.10 4 | 5 | -------------------------------------------------------------------------------- /img/demo-vault-canvas-graph-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfarragher/obsidiantools-demo/c55197aa68685bce13b8e417acad1872cc62363c/img/demo-vault-canvas-graph-example.png -------------------------------------------------------------------------------- /img/demo-vault-networkx-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfarragher/obsidiantools-demo/c55197aa68685bce13b8e417acad1872cc62363c/img/demo-vault-networkx-graph.png -------------------------------------------------------------------------------- /img/demo-vault_obsidian-app-actual-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfarragher/obsidiantools-demo/c55197aa68685bce13b8e417acad1872cc62363c/img/demo-vault_obsidian-app-actual-graph.png -------------------------------------------------------------------------------- /img/demo-vault_pyvis-graph-includes-attachments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfarragher/obsidiantools-demo/c55197aa68685bce13b8e417acad1872cc62363c/img/demo-vault_pyvis-graph-includes-attachments.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | obsidiantools==0.10.0 # lib 2 | markdown 3 | html2text 4 | pandas 5 | numpy 6 | networkx 7 | matplotlib # for demo 8 | scipy # for demo 9 | -------------------------------------------------------------------------------- /vault-stub/Crazy wall 2.canvas: -------------------------------------------------------------------------------- 1 | { 2 | "nodes":[ 3 | {"id":"7ee7e59e29a5b091","x":-125,"y":-30,"width":250,"height":60,"type":"text","text":"Now we're getting meta..."} 4 | ], 5 | "edges":[] 6 | } -------------------------------------------------------------------------------- /vault-stub/Crazy wall.canvas: -------------------------------------------------------------------------------- 1 | { 2 | "nodes":[ 3 | {"id":"0fb63a211244ab98","x":-338,"y":-1140,"width":504,"height":294,"color":"6","type":"text","text":"# Purple\n## Shades\n- [[Prince]] Ultra-Violet Pantone ![#5f4b8b](https://placehold.co/15x15/5f4b8b/5f4b8b.png) `#5f4b8b`\n- A colour for Obsidian.md: ![#826ed9](https://placehold.co/15x15/826ed9/826ed9.png) `#826ed9`\n"}, 4 | {"id":"5b04fb9cabc4b282","x":151,"y":540,"width":250,"height":173,"type":"text","text":"# Phil Collins\n\nSongs:\n- [[Sussudio]]"}, 5 | {"id":"8f032f9a663e27b5","x":-1072,"y":60,"width":400,"height":291,"type":"file","file":"Isolated note.md"}, 6 | {"id":"d3f112f83760095a","x":194,"y":-338,"width":414,"height":274,"type":"link","url":"https://www.youtube.com/watch?v=rblt2EtFfC4"}, 7 | {"id":"c168506f5b075d91","x":311,"y":60,"width":400,"height":400,"type":"file","file":"Sussudio.md"}, 8 | {"id":"9d13d42f967553bf","x":-547,"y":-715,"width":461,"height":603,"color":"#5f4b8b","type":"text","text":"# Prince\n\n## Playlist ideas\n90-120 BPM 'sampler' playlist ideas (chronological for now):\n- [[1999]]\n- Let's Go Crazy\n- 17 Days\n- She's Always in My Hair\n- Kiss\n- Sign o' the Times\n- Alphabet Street\n- Cream\n- 7\n- The Most Beautiful Girl in the World\n- Space\n- Right Back Here in My Arms\n- Love Sign [Shock G's Silky Mix]\n- Musicology\n"}, 9 | {"id":"a10aaf054261706d","x":-567,"y":-735,"width":1298,"height":1468,"type":"group","label":"Music"}, 10 | {"id":"2919b72bf3df3791","x":-1363,"y":-812,"width":491,"height":474,"type":"file","file":"Crazy wall 2.canvas"} 11 | ], 12 | "edges":[ 13 | {"id":"7c87f0b9f93e8be6","fromNode":"c168506f5b075d91","fromSide":"left","toNode":"8f032f9a663e27b5","toSide":"right"}, 14 | {"id":"f80cf8b38fb92c56","fromNode":"5b04fb9cabc4b282","fromSide":"right","toNode":"c168506f5b075d91","toSide":"bottom","color":"3"}, 15 | {"id":"cd6d56bb9268f597","fromNode":"d3f112f83760095a","fromSide":"right","toNode":"c168506f5b075d91","toSide":"top","color":"3","label":"inspires?"}, 16 | {"id":"ed82518d156b6279","fromNode":"9d13d42f967553bf","fromSide":"right","toNode":"d3f112f83760095a","toSide":"top","color":"6"} 17 | ] 18 | } -------------------------------------------------------------------------------- /vault-stub/Isolated note.md: -------------------------------------------------------------------------------- 1 | # Isolated note 2 | This is an isolated note ~~an orphan~~. 3 | -------------------------------------------------------------------------------- /vault-stub/Sussudio.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sussudio 3 | artist: Phil Collins 4 | category: music 5 | year: 1985 6 | url: https://www.discogs.com/Phil-Collins-Sussudio/master/106239 7 | references: [[[American Psycho (film)]], Polka Party!] 8 | chart_peaks: 9 | - US: 1 10 | - UK: 12 11 | --- 12 | # Sussudio 13 | 14 | Another word with absolutely no meaning 😄 15 | 16 | This will be a note inside the vault dir. Others will be lipsum in a subdirectory. 17 | 18 | ![[Sussudio.mp3]] 19 | 20 | The song has been compared to the Prince's "1999" ( #y1982 ) <- oh look, a tag! 21 | 22 | ![[1999.flac]] 23 | 24 | More tags: 25 | - #y_1982 26 | - #y-1982 27 | - #y1982/sep 28 | - #y2000/party-over/oops/out-of-time 29 | 30 | However these shouldn't be recognised as tags: 31 | - (#y1985 ) 32 | - #1985 33 | - [[American Psycho (film)#Patrick Bateman]] 34 | - \#hash_char_not_tag 35 | 36 | ```python 37 | # #code_comment_not_tag 38 | # #code-comment-not-tag 39 | 40 | if '#i_just_say_the_word': 41 | print('It feels so good') 42 | ``` 43 | -------------------------------------------------------------------------------- /vault-stub/lipsum/Alimenta.md: -------------------------------------------------------------------------------- 1 | # Alimenta 2 | Food for thought: [[Crazy wall 2.canvas]] 3 | 4 | ## Ulciscitur ingemuere 5 | 6 | Lorem markdownum ut innixus *vocibus illam confessis* visuras urnaque, ire sic, 7 | arcus Epimethida omnia accessi [tibi](http://fugitaer.net/dignus)! Coeranon et 8 | abstulit amor est quoque in aliis paterque huius Imbreus, fui quas addidit [[Manus|manus]] [[Bacchus|bacchaeque]]. Silva gracili [[Amor|amat]]! Nunc stet haec campis tumens greges? 9 | 10 | Dedit hoc in quamvis reliquit *incrementa albentibus* laverat, ore et quae, 11 | ossa. Rura illi intima est fato forem anhelitus cursu silvis, tempore omnia, 12 | pendebant. Et **regnumque aequora**, care me, sum Nelei quem vulnus passimque 13 | castique color sparsit silent. Tu inquit crudelis conrepta aures, procubuere 14 | cornua in annis, grandia luce [Cephisias](http://www.a-iuveni.com/): circumdare, 15 | postquam. Alphenor iubas numen dici equus tractataque in enim muro omnia 16 | piscator At vulnere Memnonis poenas laborant interea adepta. 17 | 18 | ## Fieri duxisses vates siqua viribus dotalem 19 | 20 | [[Ne fuit#Suisque Tritonidos iacet fugit paterque|Fuit]] alios latratibus enim: est post cinctum ait rapuit tumet terraeque 21 | **laesasque** pectora **minister** [[Virtus|virtus]]? Illis sua, sic admissum sunt victa 22 | ipse talia, cum [materno](http://cibos.net/venulus-redito.html), iuncta per 23 | quamvis dummodo defuerunt in videt. **Aequo** nec patrias cladis [[Brevissimus moenia | moenia]] 24 | sententia rebus rapite spectata geminas? Vota [cepit](http://et-pronus.com/), 25 | astu mihi virginis oculos illius! [Opus virtute](http://iuppiter.net/): sic non 26 | nisi! 27 | 28 | Et fornace saxa, questus virginitate voti duris parte. Qui teste. 29 | 30 | ## Gente mihi nec trabesque sanguine gigantas tegi 31 | 32 | Rigescunt mater haerentia retinentia voce, [[Tarpeia]] nec proles inde gramine senes 33 | in digiti. Digitis ferens; det dea tura arce meritumque dederant oblectamina 34 | pectora. Aede prima, unius, per quod seductus animalibus simul. 35 | 36 | > Versant est tamen silvas, anguigenae poscat comitatur abdita, Iamque. Captam 37 | > humus. Insidias Mnemonides dumque festa. Uno aquis talibus saepe. 38 | 39 | Metus dolore ubique videnda tolleret, medio cupidine tendat me latratu etiamnum. 40 | Ramum metus, inmensi tecta secuit meorum et cicatrix lucoque nepotum: sit et 41 | Crocon in caluere ramum cum mulcet. 42 | 43 | Metuunt conspecta [[Tydides]] famem, et **Phryges vix est** color tu aut. Tellure 44 | atque laudaret! Eo certum rupta, cur tum latere premit qui pariter aureus? 45 | Pulcherrime dolor postquam. Aura rotat **mihi Cilix venerat** superare amnem 46 | nisi [[Vita | vitae]], nova pulsa laude itque parsque. 47 | 48 | ## More wikilinks 49 | [[Bacchus]] [[Bacchus]] [[Bacchus]] 50 | -------------------------------------------------------------------------------- /vault-stub/lipsum/Brevissimus moenia.md: -------------------------------------------------------------------------------- 1 | # Brevissimus moenia 2 | 3 | ## Gente cum ratem profanus 4 | 5 | Lorem markdownum forsitan quam mirum cereris tetigere captum occuluit, confudit 6 | nec templa, es iusta cultu colla. Possit *[[Tarpeia]] et lumina* toto, pius inpius 7 | surdaeque una partimque femina cunctantem adsueto! Relinquo curalium amnis 8 | deflevit gradumque Dorylas miseram? 9 | 10 | - Suco tethys foret te Lyrnesia primo 11 | - Lenta caede parte nubila praesens 12 | - Tellurem nomenque deique ora fraterque dabat Cephalum 13 | - Vult Cythereia quas dixit dolebat natarum 14 | 15 | Requiram coniunx. Agat puris vel madida vasti sternit repperit ab, setius 16 | flumina putabant simul et post servantes parte rumpit sagittas. Conatur 17 | inmittitur dabat, agmine rogabo simulantis [cadunt](http://www.alii.io/). Ferro 18 | tibi? Equos remansit in exercere: semimarem *Ixion*, delectat bellica. 19 | 20 | ## Auro sub primum carnes 21 | 22 | Opem rure corpora hunc male hanc tellure et in arma capientur parsque nunc 23 | concordia in **quod dente**. Ac et sorores scopulum manus: tamen morte timentur 24 | postibus, Lycus perque. Et ego cum lympha est manet attollit *vultus*. Uteroque 25 | **vos** quam Aeacides veneno. Pascere [[Caelum|caelo]], Persidaque corpus famulas, tacui 26 | detrahit quaerere tactusque nec iungat monstra iussa, aut. 27 | 28 | > Sedesque patriis heros, uvis unius cepisse, candidioribus hastam! Quae arte 29 | > palustribus liquida pyram *magna*. Non quod *perstant*. Nata **lumina** siqua; 30 | > nihil nova tali precor flores patiare. 31 | 32 | Pompae nec quod non aequalis, non Medea signum, spatioque unius! [Non 33 | Sole](http://fronti.com/tumiseris.html), si quisquam pulvere, cum dum, quod. 34 | 35 | Moriturus postquam. Viri per equique baculo tellus clavigeram gravi edidicitque 36 | vasta expulsi, taurum. Dona momordi, ut laesi flagratque meri hanc *gaudet*? At 37 | inquit Gallicus promissis edax; [[Vita|vitam]] Livor telique lustrantem esse: spes haec 38 | coeperat? -------------------------------------------------------------------------------- /vault-stub/lipsum/Causam mihi.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Causam mihi 3 | author: Ovid 4 | category: literature 5 | year: 8 6 | language: la 7 | description: {{description}} 8 | --- 9 | # Causam mihi 10 | 11 | ## Tu perque fit poposcerat duas obvius omnia 12 | 13 | Lorem markdownum praeterit cadentem et cognita tremor de guttura vixque 14 | regnabat, tetigit! Et in poena imitatur furto cuspide illuc, prompsit, in 15 | ignara. [[Dives]] eunt Cycnum. 16 | 17 | - Sic nemus unda superstes valeo auris vestro 18 | - Ultimus inportunusque Rhenum sollicitumque iuga dum [[Manus|manus]] 19 | - In brevis 20 | - Mediis pomaque 21 | - Mihi Nil 22 | - Diu [[Ne fuit|fuit]] sumpserat nulli 23 | 24 | ## Trahens ipsum iudice fervoribus figurae dixit nefas 25 | 26 | Membra titulis scilicet magistra habet facta profanat, hoc quam cacumine. Anser 27 | aura si **postquam Phoebus aestus**. Nec ferro ostendens ea moratus stridunt 28 | ventis temerarius **lacertis fixumque** vocisque. Invida quam nisi tum miles 29 | occulto cvrrvs de lustrant temerasse *poplite validosque motatque* hanc animae. 30 | 31 | - Medio iam ero mox perque obscura stimulis 32 | - Limosi ludit nil 33 | - Ut erectus canities patrem 34 | - Ministri et rates procul 35 | 36 | ## Sternuntur secum 37 | 38 | Cur verbaque, deam pallor nomen? Ignibus pictae; et et autem arguis quem, 39 | divulsaque. 40 | 41 | - Horret [[Aetna]] 42 | - Si hostem aeterno coniciunt dignus 43 | - Quidem has externa 44 | - Perque ab et posset 45 | - Fluminaque medium tradit figuras laudemur iniustum tamen 46 | - Carnibus perdiderant vices 47 | 48 | Eruiturque hunc: metu mediaque et accipite forma. Et fortuna divum, mea ad 49 | glomeravit diemque. 50 | 51 | *Litus* aut adveniet prior. Mox simul Iliades, nemo, aut tradat in nuda per 52 | colore nec tegumen nisi commonuit. -------------------------------------------------------------------------------- /vault-stub/lipsum/Isolated note.md: -------------------------------------------------------------------------------- 1 | # Isolated note 2 | An isolated note in another directory. 3 | 4 | A wikilink to this note would include 'lipsum' inside it to distinguish this note from the note that shares the filename. 5 | -------------------------------------------------------------------------------- /vault-stub/lipsum/Ne fuit.md: -------------------------------------------------------------------------------- 1 | # Ne fuit 2 | 3 | ## Quique popularis Myrmidonasque incumbens forabilis animusque retro 4 | 5 | Lorem markdownum Giganteo oculos: mox palmis sanguinis ille reppulit terra. 6 | Dempto duobus omnes concipiunt Latois, cum cuncti Phylius dimittit. Et Triopeius 7 | credi, Phrygiaeque gaudent? [[Aras Teucras.md]] habet illa: Ida caede *Iason dona* ore 8 | clausaeque, fingant sagitta fiducia, et cum progeniem. 9 | 10 | Mens unus dea nant concava genitor non, et natura. Illo ait Iuppiter orare; 11 | meruisse *macies herbarum* loquor ereptus [concretam](http://vires.io/) sequens 12 | armis? Animos removit factum caesae frequens 13 | [cur](http://excoquitprotinus.net/quae.html) tam nostros dicenti tauros 14 | percensuit exire relictus nuper. Amnis musco limite, prominet e Agaue renovata 15 | data exhortantur annum anhelitus trunco est haerens? 16 | 17 | 1. Et regis contendere esset 18 | 2. Monstrare reducto perdere et poplite pastoribus quoque 19 | 3. Dissimilemque ales Cyllenius vocari finita femineae pro 20 | 4. Consternantur tuae sua Alcmene collo resolvit si 21 | 5. Sic per gravitate tamen 22 | 6. Nomine tauro iuveni coniugis quamvis 23 | 24 | ## Suisque Tritonidos iacet fugit paterque 25 | 26 | *Fatentis* prope visuras Quae Lydos didicit et superi dedere, oscula profundum 27 | gramine concurreret recentibus. Aoniis fidissima dolor illo 28 | [cultus](http://medullis-me.net/novat), in est tibi praecordia [[Manus|manus]] gelidi. Et 29 | optat ubi [[Bacchus | Baccho]] eatque *avara*, tamen, tria medio fictaque indignis, es dedi, 30 | vi mirabere adspicit? [[Amor|Amat Amoris]] dum presso solidoque iura; me en excussae 31 | verboque caesus. *Progenitore satis* telis, [ictu 32 | caudam](http://sedibus.io/levemmonstra) poterat revellit relictus ambo, *tale 33 | minima*; rostrum ausim. 34 | 35 | > Et curam. Grave me ad, ait amoris melius munera obumbrat denique, rigorem 36 | > gravis taurorum secum, calidumque. Numina tum feret sequitur quam viribus 37 | > cavas talia Tritoniaca audierat credimus et? Reliquit porrigit: tolle, filia 38 | > nervos antra; ille quid erat liceat: Midae bis nox parte Andros, et. 39 | 40 | Evomit currus, faciem avidusque sacris, [[Caelum | caelum]] tegit et. Tinctis meos, est 41 | properas ingemuit prosiliunt aetas meritisne sustinet capiebant flexere, stultae 42 | indestrictus lucem. Non te Phaethusa *corpus*. 43 | 44 | 1. Avido terra admisso ultra colloque repulso 45 | 2. Prope petiit letoque putet 46 | 3. Recessit [[Causam mihi | causam parentem]] 47 | 48 | Non factum mentita; in alios peccasse pollicita **victima medioque**. Virum 49 | vocis crines ligat, per vix, at fugiunt precatur illa. Famulis animasque non. -------------------------------------------------------------------------------- /vault-stub/lipsum/Vulnera ubera.md: -------------------------------------------------------------------------------- 1 | # Vulnera ubera 2 | 3 | ## Regnis multaque status 4 | 5 | Lorem markdownum aerias, non est tabuit clamat illo __aries deprendit arvum__ 6 | duce? Ducunt carbasa ferro [[Caelum|caelestique]] tumor Meleagros posito, seriemque 7 | lovis, hunc suo custos. Exercere sputantem comaeque siccis maxima 8 | satis effugit exspectare domo est. 9 | 10 | 1. Vir dextra an silvis exuit e profundi 11 | 2. Petit proceres insania neque iussitque conplexu relicto 12 | 3. Nubes dextra carpit repetet lyraeque utere 13 | 14 | Suam dedi aut regemque ferox fluentia vivacia at uterque furori fecundaque artes 15 | vapor tua. Inplerit ardor iram cum subsidunt: Troiae erat: ipsis damnum ait 16 | cornua tantum venientique. Erit memini et fores sculpsit, Philomela et posset 17 | cum: at enim longum paene et iubenti. 18 | 19 | ## Falcatus quid nostro ventus mirere candor arva 20 | 21 | Servet iusta expediunt, ipse mensas quam laesi, _gurgite_, humi Myrrha gladios 22 | Haemoniae dicique petii, specto. Thebas monitisque fecere furta sed Pulydamanta 23 | tendebat vellem, Ceyx et ense caudae Cecropidae vires. 24 | 25 | 1. Clamor virginitas 26 | 2. Est quoque stravit unum contigit 27 | 3. [[Tarpeia]] undecimus animi locus imago quae propago 28 | 4. Diana voce mitis delapsa 29 | 30 | Inductas Caucasus duobus erat educat mentis, oraque novo numero Rhoeti tempora 31 | transitus fortuna ecce fatemur, [[Vita|vitae]] adnuit quis. Occidit 32 | melioribus, nec mole consistere iura ad numeri anima considere accessit? Fide 33 | maxima volat. 34 | 35 | Iter fratrem equidem traiecit canis tenuit intrarunt aquae innuba, visa usum 36 | blando. Faucesque geri carent ibis serpens, qua tempore. Quos vili pumice tamen 37 | voco agitat, ad pennis tamen. --------------------------------------------------------------------------------