From afba7daf720ef9ad7a5a6473bcc7c4dc316bc530 Mon Sep 17 00:00:00 2001
From: Utsob Roy <roy@utsob.me>
Date: Fri, 20 Jan 2023 00:35:09 +0600
Subject: [PATCH 1/3] add downloaded theme support

---
 package-lock.json      | 154 +++++++++++++++++++++++++++++++++--------
 package.json           |   6 +-
 src/site/_data/meta.js |  55 ++++++---------
 src/site/get-theme.js  |  39 +++++++++++
 4 files changed, 191 insertions(+), 63 deletions(-)
 create mode 100644 src/site/get-theme.js

diff --git a/package-lock.json b/package-lock.json
index 335922225..7681aca09 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,7 @@
                 "eleventy-favicon": "^1.1.2",
                 "eleventy-plugin-toc": "^1.1.5",
                 "fs-file-tree": "^1.1.1",
+                "glob": "^8.1.0",
                 "gray-matter": "^4.0.3",
                 "lunr": "^2.3.9",
                 "markdown-it": "^13.0.1",
@@ -795,8 +796,7 @@
         "node_modules/balanced-match": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
-            "dev": true
+            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
         },
         "node_modules/base64-js": {
             "version": "1.5.1",
@@ -2237,8 +2237,7 @@
         "node_modules/fs.realpath": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-            "dev": true
+            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
         },
         "node_modules/fsevents": {
             "version": "2.3.2",
@@ -2333,20 +2332,18 @@
             "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
         },
         "node_modules/glob": {
-            "version": "7.2.0",
-            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-            "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
-            "dev": true,
+            "version": "8.1.0",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+            "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
             "dependencies": {
                 "fs.realpath": "^1.0.0",
                 "inflight": "^1.0.4",
                 "inherits": "2",
-                "minimatch": "^3.0.4",
-                "once": "^1.3.0",
-                "path-is-absolute": "^1.0.0"
+                "minimatch": "^5.0.1",
+                "once": "^1.3.0"
             },
             "engines": {
-                "node": "*"
+                "node": ">=12"
             },
             "funding": {
                 "url": "https://github.com/sponsors/isaacs"
@@ -2364,6 +2361,25 @@
                 "node": ">= 6"
             }
         },
+        "node_modules/glob/node_modules/brace-expansion": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+            "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+            "dependencies": {
+                "balanced-match": "^1.0.0"
+            }
+        },
+        "node_modules/glob/node_modules/minimatch": {
+            "version": "5.1.6",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+            "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+            "dependencies": {
+                "brace-expansion": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
         "node_modules/global": {
             "version": "4.4.0",
             "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
@@ -2660,7 +2676,6 @@
             "version": "1.0.6",
             "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
             "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-            "dev": true,
             "dependencies": {
                 "once": "^1.3.0",
                 "wrappy": "1"
@@ -3154,6 +3169,26 @@
                 "node": ">=10"
             }
         },
+        "node_modules/js-beautify/node_modules/glob": {
+            "version": "7.2.3",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+            "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+            "dev": true,
+            "dependencies": {
+                "fs.realpath": "^1.0.0",
+                "inflight": "^1.0.4",
+                "inherits": "2",
+                "minimatch": "^3.1.1",
+                "once": "^1.3.0",
+                "path-is-absolute": "^1.0.0"
+            },
+            "engines": {
+                "node": "*"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
         "node_modules/js-stringify": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
@@ -4260,7 +4295,7 @@
         "node_modules/path-is-absolute": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-            "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+            "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
             "dev": true,
             "engines": {
                 "node": ">=0.10.0"
@@ -4953,6 +4988,26 @@
                 "rimraf": "bin.js"
             }
         },
+        "node_modules/rimraf/node_modules/glob": {
+            "version": "7.2.3",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+            "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+            "dev": true,
+            "dependencies": {
+                "fs.realpath": "^1.0.0",
+                "inflight": "^1.0.4",
+                "inherits": "2",
+                "minimatch": "^3.1.1",
+                "once": "^1.3.0",
+                "path-is-absolute": "^1.0.0"
+            },
+            "engines": {
+                "node": "*"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
         "node_modules/run-parallel": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -7091,8 +7146,7 @@
         "balanced-match": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
-            "dev": true
+            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
         },
         "base64-js": {
             "version": "1.5.1",
@@ -8223,8 +8277,7 @@
         "fs.realpath": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-            "dev": true
+            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
         },
         "fsevents": {
             "version": "2.3.2",
@@ -8297,17 +8350,33 @@
             "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
         },
         "glob": {
-            "version": "7.2.0",
-            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-            "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
-            "dev": true,
+            "version": "8.1.0",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+            "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
             "requires": {
                 "fs.realpath": "^1.0.0",
                 "inflight": "^1.0.4",
                 "inherits": "2",
-                "minimatch": "^3.0.4",
-                "once": "^1.3.0",
-                "path-is-absolute": "^1.0.0"
+                "minimatch": "^5.0.1",
+                "once": "^1.3.0"
+            },
+            "dependencies": {
+                "brace-expansion": {
+                    "version": "2.0.1",
+                    "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+                    "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+                    "requires": {
+                        "balanced-match": "^1.0.0"
+                    }
+                },
+                "minimatch": {
+                    "version": "5.1.6",
+                    "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+                    "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+                    "requires": {
+                        "brace-expansion": "^2.0.1"
+                    }
+                }
             }
         },
         "glob-parent": {
@@ -8525,7 +8594,6 @@
             "version": "1.0.6",
             "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
             "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-            "dev": true,
             "requires": {
                 "once": "^1.3.0",
                 "wrappy": "1"
@@ -8893,6 +8961,22 @@
                 "editorconfig": "^0.15.3",
                 "glob": "^7.1.3",
                 "nopt": "^5.0.0"
+            },
+            "dependencies": {
+                "glob": {
+                    "version": "7.2.3",
+                    "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+                    "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+                    "dev": true,
+                    "requires": {
+                        "fs.realpath": "^1.0.0",
+                        "inflight": "^1.0.4",
+                        "inherits": "2",
+                        "minimatch": "^3.1.1",
+                        "once": "^1.3.0",
+                        "path-is-absolute": "^1.0.0"
+                    }
+                }
             }
         },
         "js-stringify": {
@@ -9757,7 +9841,7 @@
         "path-is-absolute": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-            "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+            "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
             "dev": true
         },
         "path-key": {
@@ -10319,6 +10403,22 @@
             "dev": true,
             "requires": {
                 "glob": "^7.1.3"
+            },
+            "dependencies": {
+                "glob": {
+                    "version": "7.2.3",
+                    "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+                    "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+                    "dev": true,
+                    "requires": {
+                        "fs.realpath": "^1.0.0",
+                        "inflight": "^1.0.4",
+                        "inherits": "2",
+                        "minimatch": "^3.1.1",
+                        "once": "^1.3.0",
+                        "path-is-absolute": "^1.0.0"
+                    }
+                }
             }
         },
         "run-parallel": {
diff --git a/package.json b/package.json
index 8b839ee80..dbeefce02 100644
--- a/package.json
+++ b/package.json
@@ -4,12 +4,13 @@
     "description": "",
     "main": "index.js",
     "scripts": {
-        "start": "npm-run-all build:sass --parallel watch:*",
+        "start": "npm-run-all get-theme build:sass --parallel watch:*",
         "watch:sass": "sass --watch src/site/styles:dist/styles",
         "watch:eleventy": "cross-env ELEVENTY_ENV=dev eleventy --serve",
         "build:eleventy": "cross-env ELEVENTY_ENV=prod NODE_OPTIONS=--max-old-space-size=4096 eleventy",
         "build:sass": "sass src/site/styles:dist/styles",
-        "build": "npm-run-all build:*",
+        "get-theme": "node src/site/get-theme.js",
+        "build": "npm-run-all get-theme build:*",
         "postbuild": "node src/site/lunr-index.js"
     },
     "keywords": [],
@@ -31,6 +32,7 @@
         "eleventy-favicon": "^1.1.2",
         "eleventy-plugin-toc": "^1.1.5",
         "fs-file-tree": "^1.1.1",
+        "glob": "^8.1.0",
         "gray-matter": "^4.0.3",
         "lunr": "^2.3.9",
         "markdown-it": "^13.0.1",
diff --git a/src/site/_data/meta.js b/src/site/_data/meta.js
index 9feb10c0f..9c4c5f279 100644
--- a/src/site/_data/meta.js
+++ b/src/site/_data/meta.js
@@ -1,39 +1,26 @@
 require("dotenv").config();
 const axios = require("axios");
+const fs = require("fs");
+const crypto = require("crypto");
+const glob = require("glob");
 
+module.exports = async () => {
+  let baseUrl = process.env.SITE_BASE_URL || "";
+  if (baseUrl && !baseUrl.startsWith("http")) {
+    baseUrl = "https://" + baseUrl;
+  }
+  let themeStyle = glob.sync("src/site/styles/theme.*.css")[0] || "";
+  if (themeStyle) {
+    themeStyle = themeStyle.split("site")[1];
+  }
+  const meta = {
+    env: process.env.ELEVENTY_ENV,
+    theme: process.env.THEME,
+    themeStyle,
+    baseTheme: process.env.BASE_THEME || "dark",
+    siteName: process.env.SITE_NAME_HEADER || "Digital Garden",
+    siteBaseUrl: baseUrl,
+  };
 
-module.exports = async() => {
-    let themeStyle = "";
-    let themeUrl = process.env.THEME;
-    if (themeUrl) {
-        //https://forum.obsidian.md/t/1-0-theme-migration-guide/42537
-        //Not all themes with no legacy mark have a theme.css file, so we need to check for it
-        try{
-            await axios.get(themeUrl);
-        }catch{
-            if(themeUrl.indexOf("theme.css") > -1){
-                themeUrl = themeUrl.replace("theme.css", "obsidian.css");
-            }
-            else if(themeUrl.indexOf("obsidian.css") > -1){
-                themeUrl = themeUrl.replace("obsidian.css", "theme.css");
-            }
-        }
-
-        const res = await axios.get(themeUrl);
-        themeStyle = `<style>${res.data}</style>`;
-    }
-    let baseUrl = process.env.SITE_BASE_URL || "";
-    if(baseUrl && !baseUrl.startsWith("http")){
-        baseUrl = "https://" + baseUrl;
-    }
-    const meta ={
-        env: process.env.ELEVENTY_ENV,
-        theme: process.env.THEME,
-        themeStyle: themeStyle,
-        baseTheme: process.env.BASE_THEME || "dark",
-        siteName: process.env.SITE_NAME_HEADER || "Digital Garden",
-        siteBaseUrl: baseUrl,
-    };
-
-    return meta;
+  return meta;
 };
diff --git a/src/site/get-theme.js b/src/site/get-theme.js
new file mode 100644
index 000000000..f752516de
--- /dev/null
+++ b/src/site/get-theme.js
@@ -0,0 +1,39 @@
+require("dotenv").config();
+const axios = require("axios");
+const fs = require("fs");
+const crypto = require("crypto");
+const glob = require("glob");
+
+async function getTheme() {
+  let themeUrl = process.env.THEME;
+  if (themeUrl) {
+    //https://forum.obsidian.md/t/1-0-theme-migration-guide/42537
+    //Not all themes with no legacy mark have a theme.css file, so we need to check for it
+    try {
+      await axios.get(themeUrl);
+    } catch {
+      if (themeUrl.indexOf("theme.css") > -1) {
+        themeUrl = themeUrl.replace("theme.css", "obsidian.css");
+      } else if (themeUrl.indexOf("obsidian.css") > -1) {
+        themeUrl = themeUrl.replace("obsidian.css", "theme.css");
+      }
+    }
+
+    const res = await axios.get(themeUrl);
+    try {
+      const existing = glob.sync("src/site/styles/theme.*.css");
+      existing.forEach((file) => {
+        fs.rmSync(file);
+      });
+    } catch {}
+    const hashSum = crypto.createHash("sha256");
+    hashSum.update(res.data);
+    const hex = hashSum.digest("hex");
+    fs.writeFileSync(
+      `src/site/styles/theme.${hex.substring(0, 8)}.css`,
+      res.data
+    );
+  }
+}
+
+getTheme();

From d5b2409a0b8bdd557ca1bcede36db752a30f9a5b Mon Sep 17 00:00:00 2001
From: Ole Eskild Steensen <ole@savvy.no>
Date: Sat, 21 Jan 2023 12:03:39 +0100
Subject: [PATCH 2/3] Add support for slashes in tags

---
 .eleventy.js | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/.eleventy.js b/.eleventy.js
index ca618f420..d53e6980c 100644
--- a/.eleventy.js
+++ b/.eleventy.js
@@ -8,6 +8,8 @@ const { parse } = require("node-html-parser");
 
 const { headerToId, namedHeadingsFilter } = require("./src/helpers/utils");
 
+const tagRegex = /(^|\s|\>)(#[^\s!@#$%^&*()=+\.,\[{\]};:'"?><]+)(?!([^<]*>))/g;
+
 module.exports = function (eleventyConfig) {
   let markdownLib = markdownIt({
     breaks: true,
@@ -194,7 +196,7 @@ module.exports = function (eleventyConfig) {
     return (
       str &&
       str.replace(
-        /(^|\s|\>)(#[^\s!@#$%^&*()=+\.\/,\[{\]};:'"?><]+)(?!([^<]*>))/g,
+        tagRegex,
         function (match, precede, tag) {
           return `${precede}<a class="tag" onclick="toggleTagSearch(this)">${tag}</a>`;
         }
@@ -207,7 +209,7 @@ module.exports = function (eleventyConfig) {
     let match =
       str &&
       str.match(
-        /(^|\s|\>)(#[^\s!@#$%^&*()=+\.\/,\[{\]};:'"?><]+)(?!([^<]*>))/g
+        tagRegex,
       );
     if (match) {
       tags = match

From 0fe8b10233c3b5191eb1c5d687f49df18990c1ab Mon Sep 17 00:00:00 2001
From: Ole Eskild Steensen <ole@savvy.no>
Date: Sat, 21 Jan 2023 12:12:59 +0100
Subject: [PATCH 3/3] Fix stylesheet link, and add new file to plugin-info

---
 .gitignore                                   | 1 +
 plugin-info.json                             | 3 ++-
 src/site/_includes/components/pageheader.njk | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index eee7383df..a19ff3e2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ node_modules
 dist
 netlify/functions/search/data.json
 netlify/functions/search/index.json
+src/site/styles/theme.*.css
 # Local Netlify folder
 .netlify
 .idea/
\ No newline at end of file
diff --git a/plugin-info.json b/plugin-info.json
index 9b4ee362e..ee6055d28 100644
--- a/plugin-info.json
+++ b/plugin-info.json
@@ -48,6 +48,7 @@
             "src/helpers/constants.js",
             "src/helpers/utils.js",
             "src/helpers/linkUtils.js",
-            "netlify/functions/search/search.js"
+            "netlify/functions/search/search.js",
+            "src/site/get-theme.js"
         ]
 }
\ No newline at end of file
diff --git a/src/site/_includes/components/pageheader.njk b/src/site/_includes/components/pageheader.njk
index 4e6178d7b..0d400ba3b 100644
--- a/src/site/_includes/components/pageheader.njk
+++ b/src/site/_includes/components/pageheader.njk
@@ -23,7 +23,7 @@
 <link href="/styles/digital-garden-base.css" rel="stylesheet">
 {%-if meta.themeStyle%}
     <link href="/styles/obsidian-base.css" rel="stylesheet">
-    {{meta.themeStyle | safe}}
+    <link href="{{meta.themeStyle}}" rel="stylesheet">
 {% else %}
     <link href="/styles/style.css" rel="stylesheet">
 {%endif%}