From a70e846b0a14f3065bbf613221fee0e3b09c12ef Mon Sep 17 00:00:00 2001
From: Jacky Zhao <j.zhao2k19@gmail.com>
Date: Tue, 1 Aug 2023 22:47:16 -0700
Subject: [PATCH] flag to allow ofm replace in html embed

---
 content/advanced/architecture.md     |  1 +
 content/advanced/paths.md            |  0
 content/configuration.md             | 22 +++++++++-
 content/index.md                     |  2 +-
 package-lock.json                    | 63 ++++++++++++++++++++++++++--
 package.json                         |  2 +
 quartz/plugins/transformers/links.ts |  1 +
 quartz/plugins/transformers/ofm.ts   | 40 +++++++++++++++++-
 8 files changed, 124 insertions(+), 7 deletions(-)
 create mode 100644 content/advanced/architecture.md
 create mode 100644 content/advanced/paths.md

diff --git a/content/advanced/architecture.md b/content/advanced/architecture.md
new file mode 100644
index 0000000..688fd75
--- /dev/null
+++ b/content/advanced/architecture.md
@@ -0,0 +1 @@
+how does quartz work? great question lol
diff --git a/content/advanced/paths.md b/content/advanced/paths.md
new file mode 100644
index 0000000..e69de29
diff --git a/content/configuration.md b/content/configuration.md
index 1545d66..e31dbc2 100644
--- a/content/configuration.md
+++ b/content/configuration.md
@@ -79,6 +79,26 @@ If you'd like to make your own plugins, read the guide on [[making plugins]] for
 
 ### Layout
 
-Certain emitters may also output [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) files. To enable easy customization, these emitters allow you to fully rearrange the layout of the page.
+Certain emitters may also output [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) files. To enable easy customization, these emitters allow you to fully rearrange the layout of the page. The default page layouts can be found in `quartz.layout.ts`.
+
+Ultimately, each page is composed of multiple different sections which contain `QuartzComponents`. The following code snippet lists all of the valid sections that you can add components to:
+
+```typescript title="quartz/cfg.ts"
+export interface FullPageLayout {
+  head: QuartzComponent
+  header: QuartzComponent[]
+  beforeBody: QuartzComponent[]
+  pageBody: QuartzComponent
+  left: QuartzComponent[]
+  right: QuartzComponent[]
+  footer: QuartzComponent
+}
+```
+
+These correspond to following parts of the page:
 
 ### Components
+
+See [a list of all the components](./tags/component) for all available components.
+
+### Style
diff --git a/content/index.md b/content/index.md
index 5c32c23..050ce78 100644
--- a/content/index.md
+++ b/content/index.md
@@ -6,7 +6,7 @@ Quartz is a fast, batteries-included static-site generator that transforms Markd
 
 ## 🪴 Get Started
 
-Quartz requires **at least [Node](https://nodejs.org/) v16** to function correctly. In your terminal of choice, enter the following commands line by line:
+Quartz requires **at least [Node](https://nodejs.org/) v18.14** to function correctly. In your terminal of choice, enter the following commands line by line:
 
 ```shell
 git clone https://github.com/jackyzha0/quartz.git
diff --git a/package-lock.json b/package-lock.json
index 7bb72bc..3e106a6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,12 +21,14 @@
         "github-slugger": "^2.0.0",
         "globby": "^13.1.4",
         "gray-matter": "^4.0.3",
+        "hast-util-to-html": "^8.0.4",
         "hast-util-to-jsx-runtime": "^1.2.0",
         "hast-util-to-string": "^2.0.0",
         "is-absolute-url": "^4.0.1",
         "js-yaml": "^4.1.0",
         "lightningcss": "^1.21.5",
         "mdast-util-find-and-replace": "^2.2.2",
+        "mdast-util-to-hast": "^12.3.0",
         "mdast-util-to-string": "^3.2.0",
         "micromorph": "^0.4.5",
         "plausible-tracker": "^0.3.8",
@@ -1414,11 +1416,11 @@
       "dev": true
     },
     "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz",
+      "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==",
       "dependencies": {
-        "@types/unist": "*"
+        "@types/unist": "^2"
       }
     },
     "node_modules/@types/js-yaml": {
@@ -1736,6 +1738,24 @@
         "url": "https://github.com/sponsors/wooorm"
       }
     },
+    "node_modules/character-entities-html4": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+      "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/character-entities-legacy": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+      "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/chokidar": {
       "version": "3.5.3",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -2972,6 +2992,28 @@
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
       "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
     },
+    "node_modules/hast-util-to-html": {
+      "version": "8.0.4",
+      "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz",
+      "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==",
+      "dependencies": {
+        "@types/hast": "^2.0.0",
+        "@types/unist": "^2.0.0",
+        "ccount": "^2.0.0",
+        "comma-separated-tokens": "^2.0.0",
+        "hast-util-raw": "^7.0.0",
+        "hast-util-whitespace": "^2.0.0",
+        "html-void-elements": "^2.0.0",
+        "property-information": "^6.0.0",
+        "space-separated-tokens": "^2.0.0",
+        "stringify-entities": "^4.0.0",
+        "zwitch": "^2.0.4"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/hast-util-to-jsx-runtime": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-1.2.0.tgz",
@@ -5404,6 +5446,19 @@
         "node": ">=8"
       }
     },
+    "node_modules/stringify-entities": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz",
+      "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==",
+      "dependencies": {
+        "character-entities-html4": "^2.0.0",
+        "character-entities-legacy": "^3.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/strip-ansi": {
       "version": "7.1.0",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
diff --git a/package.json b/package.json
index cfd1d15..8a1d483 100644
--- a/package.json
+++ b/package.json
@@ -40,12 +40,14 @@
     "github-slugger": "^2.0.0",
     "globby": "^13.1.4",
     "gray-matter": "^4.0.3",
+    "hast-util-to-html": "^8.0.4",
     "hast-util-to-jsx-runtime": "^1.2.0",
     "hast-util-to-string": "^2.0.0",
     "is-absolute-url": "^4.0.1",
     "js-yaml": "^4.1.0",
     "lightningcss": "^1.21.5",
     "mdast-util-find-and-replace": "^2.2.2",
+    "mdast-util-to-hast": "^12.3.0",
     "mdast-util-to-string": "^3.2.0",
     "micromorph": "^0.4.5",
     "plausible-tracker": "^0.3.8",
diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts
index 7e8a278..f5bfdfc 100644
--- a/quartz/plugins/transformers/links.ts
+++ b/quartz/plugins/transformers/links.ts
@@ -47,6 +47,7 @@ export const CrawlLinks: QuartzTransformerPlugin<Partial<Options> | undefined> =
                   return targetCanonical === fileName
                 })
 
+                // only match, just use it
                 if (matchingFileNames.length === 1) {
                   const targetSlug = canonicalizeServer(matchingFileNames[0])
                   return (resolveRelative(curSlug, targetSlug) + targetAnchor) as RelativeURL
diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts
index 4a45b02..23b97d6 100644
--- a/quartz/plugins/transformers/ofm.ts
+++ b/quartz/plugins/transformers/ofm.ts
@@ -1,7 +1,7 @@
 import { PluggableList } from "unified"
 import { QuartzTransformerPlugin } from "../types"
 import { Root, HTML, BlockContent, DefinitionContent, Code } from "mdast"
-import { findAndReplace } from "mdast-util-find-and-replace"
+import { Replace, findAndReplace as mdastFindReplace } from "mdast-util-find-and-replace"
 import { slug as slugAnchor } from "github-slugger"
 import rehypeRaw from "rehype-raw"
 import { visit } from "unist-util-visit"
@@ -10,6 +10,9 @@ import { JSResource } from "../../resources"
 // @ts-ignore
 import calloutScript from "../../components/scripts/callout.inline.ts"
 import { FilePath, canonicalizeServer, pathToRoot, slugTag, slugifyFilePath } from "../../path"
+import { toHast } from "mdast-util-to-hast"
+import { toHtml } from "hast-util-to-html"
+import { PhrasingContent } from "mdast-util-find-and-replace/lib"
 
 export interface Options {
   comments: boolean
@@ -18,6 +21,7 @@ export interface Options {
   callouts: boolean
   mermaid: boolean
   parseTags: boolean
+  enableInHtmlEmbed: boolean
 }
 
 const defaultOptions: Options = {
@@ -27,6 +31,7 @@ const defaultOptions: Options = {
   callouts: true,
   mermaid: true,
   parseTags: true,
+  enableInHtmlEmbed: false,
 }
 
 const icons = {
@@ -117,6 +122,39 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
   userOpts,
 ) => {
   const opts = { ...defaultOptions, ...userOpts }
+
+  const findAndReplace = opts.enableInHtmlEmbed
+    ? (tree: Root, regex: RegExp, replace?: Replace | null | undefined) => {
+        if (replace) {
+          const mdastToHtml = (ast: PhrasingContent) => {
+            const hast = toHast(ast, { allowDangerousHtml: true })!
+            return toHtml(hast, { allowDangerousHtml: true })
+          }
+
+          visit(tree, "html", (node: HTML) => {
+            if (typeof replace === "string") {
+              node.value = node.value.replace(regex, replace)
+            } else {
+              node.value = node.value.replaceAll(regex, (substring: string, ...args) => {
+                const replaceValue = replace(substring, ...args)
+                if (typeof replaceValue === "string") {
+                  return replaceValue
+                } else if (Array.isArray(replaceValue)) {
+                  return replaceValue.map(mdastToHtml).join("")
+                } else if (typeof replaceValue === "object" && replaceValue !== null) {
+                  return mdastToHtml(replaceValue)
+                } else {
+                  return substring
+                }
+              })
+            }
+          })
+        }
+
+        mdastFindReplace(tree, regex, replace)
+      }
+    : mdastFindReplace
+
   return {
     name: "ObsidianFlavoredMarkdown",
     textTransform(_ctx, src) {