From c5892fa6fe1d848ab3f37170fb346df157b6b942 Mon Sep 17 00:00:00 2001
From: sloane <1699281+sloanelybutsurely@users.noreply.github.com>
Date: Sat, 24 Feb 2024 10:32:07 -0500
Subject: [PATCH] start adding pagefind

---
 .tool-versions                          |  1 +
 assets/css/app.css                      |  8 ++++++++
 assets/js/app.js                        |  1 -
 assets/tailwind.config.js               |  1 +
 config/config.exs                       |  6 +++---
 lib/sloane_sh/build.ex                  |  5 ++---
 lib/sloane_sh/layouts/partials.ex       | 12 +++++-------
 lib/sloane_sh/markdown.ex               | 16 ++++++----------
 mix.exs                                 |  9 +++++++--
 mix.lock                                |  1 +
 priv/site/layouts/page.html.eex         |  2 +-
 priv/site/layouts/post.html.eex         |  2 +-
 priv/site/layouts/root.html.eex         |  8 ++++----
 priv/site/pages/search.md               | 13 +++++++++++++
 priv/site/posts/2024-02-16-test-post.md |  3 +++
 15 files changed, 56 insertions(+), 32 deletions(-)
 create mode 100644 priv/site/pages/search.md

diff --git a/.tool-versions b/.tool-versions
index 1c43fd8..7547e7c 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1,2 +1,3 @@
 erlang 26.2.2
 elixir 1.16.1-otp-26
+nodejs 20.11.1
diff --git a/assets/css/app.css b/assets/css/app.css
index 71a77f0..091e0d3 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -2,3 +2,11 @@
 @import "tailwindcss/components";
 @import "tailwindcss/utilities";
 
+@media (perfers-color-scheme: dark) {
+  --pagefind-ui-primary: #eeeeee;
+  --pagefind-ui-text: #eeeeee;
+  --pagefind-ui-background: #152028;
+  --pagefind-ui-border: #152028;
+  --pagefind-ui-tag: #152028;
+}
+
diff --git a/assets/js/app.js b/assets/js/app.js
index 1bbc1bd..e69de29 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -1 +0,0 @@
-console.log('Hello, World!')
diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js
index 4c2f640..ea16120 100644
--- a/assets/tailwind.config.js
+++ b/assets/tailwind.config.js
@@ -8,6 +8,7 @@ module.exports = {
     './js/**/*.js',
     '../lib/sloane_sh/layouts/*.ex',
     '../priv/site/**/*.*ex',
+    '../priv/site/**/*.md',
   ],
   theme: {
     container: {
diff --git a/config/config.exs b/config/config.exs
index 81f00f4..7321caa 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -8,7 +8,7 @@ config :tailwind,
     args: ~w(
       --config=tailwind.config.js
       --input=css/app.css
-      --output=../priv/output/assets/app.css
+      --output=../priv/output/assets/css/app.css
     ),
     cd: Path.expand("../assets", __DIR__)
   ]
@@ -16,7 +16,7 @@ config :tailwind,
 config :esbuild,
   version: "0.20.1",
   default: [
-    args: ~w(js/app.js --bundle --target=es2016 --outdir=../priv/output/assets),
+    args: ~w(js/app.js --bundle --outdir=../priv/output/assets/js),
     cd: Path.expand("../assets", __DIR__),
-    env: %{ "NODE_PATH" => Path.expand("../deps", __DIR__) }
+    env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
   ]
diff --git a/lib/sloane_sh/build.ex b/lib/sloane_sh/build.ex
index 06b128d..5f33f30 100644
--- a/lib/sloane_sh/build.ex
+++ b/lib/sloane_sh/build.ex
@@ -31,7 +31,7 @@ defmodule SloaneSH.Build do
     path = Path.join(ctx.config.pages_dir, page)
 
     with {:ok, data} <- File.read(path),
-         {:ok, md} <- Markdown.transform(ctx, data),
+      {:ok, md} <- Markdown.transform(ctx, data),
          contents = Layouts.page_layout(ctx, md.attrs, md.html),
          html = Layouts.root_layout(ctx, md.attrs, contents),
          :ok <- Write.page(ctx, page, html) do
@@ -45,7 +45,7 @@ defmodule SloaneSH.Build do
     path = Path.join(ctx.config.posts_dir, post)
 
     with {:ok, data} <- File.read(path),
-         {:ok, md} <- Markdown.transform(ctx, data),
+      {:ok, md} <- Markdown.transform(ctx, data),
          contents = Layouts.post_layout(ctx, md.attrs, md.html),
          html = Layouts.root_layout(ctx, md.attrs, contents),
          :ok <- Write.post(ctx, post, html) do
@@ -56,7 +56,6 @@ defmodule SloaneSH.Build do
   end
 
   def copy_img(%Context{} = ctx) do
-
     ctx
   end
 end
diff --git a/lib/sloane_sh/layouts/partials.ex b/lib/sloane_sh/layouts/partials.ex
index d592538..fe1fe22 100644
--- a/lib/sloane_sh/layouts/partials.ex
+++ b/lib/sloane_sh/layouts/partials.ex
@@ -8,15 +8,13 @@ defmodule SloaneSH.Layouts.Partials do
     :def,
     :header,
     ~S"""
-    <header class="flex flex-row justify-between gap-2 border-b border-neutral-700 pb-4 mb-2">
-      <%= if attrs[:title] do %>
-        <h1 class="text-3xl font-bold"><%= attrs[:title] %></h1>
-      <% end %>
-    <div class="flex flex-col gap-2 <%= cx("items-end": attrs[:title]) %>">
+    <header class="flex flex-row justify-between gap-2 border-b border-neutral-700 pb-4 mb-2" data-pagefind-ignore>
+      <div class="flex flex-col gap-2">
         <a href="/"><h1 class="text-2xl">sloane.sh</h1></a>
-        <nav class="flex flex-row gap-2 text-lg">
+        <nav class="flex flex-row gap-2 text-xl">
           <a href="/" class="<%= cx(underline: attrs[:permalink] == "/") %>">home</a>
-          <a href="/writing" class="<%= cx(underline: Map.get(attrs, :permalink, "") =~ ~r[^/posts]) %>">writing</a>
+          <a href="/posts" class="<%= cx(underline: Map.get(attrs, :permalink, "") =~ ~r[^/posts]) %>">posts</a>
+          <a href="/search" class="<%= cx(underline: attrs[:permalink] == "/search") %>">search</a>
         </nav>
       </div>
     </header>
diff --git a/lib/sloane_sh/markdown.ex b/lib/sloane_sh/markdown.ex
index db72084..e8ed4d8 100644
--- a/lib/sloane_sh/markdown.ex
+++ b/lib/sloane_sh/markdown.ex
@@ -12,22 +12,20 @@ defmodule SloaneSH.Markdown do
   typedstruct do
     field :attrs, map(), default: %{}
     field :html, String.t(), default: ""
+    field :text, String.t(), default: ""
   end
 
   def transform(%Context{} = ctx, data) when is_binary(data) do
-    data
-    |> FrontMatter.parse(ctx)
-    |> parse_markdown(ctx)
-  end
-
-  defp parse_markdown({:ok, attrs, body}, _ctx) do
-    with {:ok, html, msgs} <- Earmark.as_html(body) do
+    with {:ok, attrs, body} <- FrontMatter.parse(data, ctx),
+         {:ok, html, msgs} <- Earmark.as_html(body),
+         {:ok, html_tree} <- Floki.parse_fragment(html) do
       for msg <- msgs, do: Logger.warning(msg)
 
       {:ok,
        %Markdown{
          attrs: attrs,
-         html: html
+         html: html,
+         text: Floki.text(html_tree, sep: " ")
        }}
     else
       {:error, _, msgs} ->
@@ -38,6 +36,4 @@ defmodule SloaneSH.Markdown do
         :error
     end
   end
-
-  defp parse_markdown(other, _ctx), do: other
 end
diff --git a/mix.exs b/mix.exs
index ed9cc1f..66f38cb 100644
--- a/mix.exs
+++ b/mix.exs
@@ -30,13 +30,18 @@ defmodule SloaneSH.MixProject do
       {:bandit, "~> 1.2"},
       {:tailwind, "~> 0.2"},
       {:toml, "~> 0.7"},
-      {:esbuild, "~> 0.8"}
+      {:esbuild, "~> 0.8"},
+      {:floki, "~> 0.35"}
     ]
   end
 
   defp aliases do
     [
-      "assets.deploy": ["tailwind default --minify"]
+      "assets.deploy": [
+        "tailwind default --minify",
+        "esbuild default --minify --sourcemap --target=chrome58,firefox57,safari11,edge16"
+      ],
+      "site.index": "cmd npx -y pagefind --site priv/output/"
     ]
   end
 end
diff --git a/mix.lock b/mix.lock
index b785465..e7c907a 100644
--- a/mix.lock
+++ b/mix.lock
@@ -5,6 +5,7 @@
   "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"},
   "esbuild": {:hex, :esbuild, "0.8.1", "0cbf919f0eccb136d2eeef0df49c4acf55336de864e63594adcea3814f3edf41", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "25fc876a67c13cb0a776e7b5d7974851556baeda2085296c14ab48555ea7560f"},
   "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"},
+  "floki": {:hex, :floki, "0.35.4", "cc947b446024732c07274ac656600c5c4dc014caa1f8fb2dfff93d275b83890d", [:mix], [], "hexpm", "27fa185d3469bd8fc5947ef0f8d5c4e47f0af02eb6b070b63c868f69e3af0204"},
   "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
   "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
   "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
diff --git a/priv/site/layouts/page.html.eex b/priv/site/layouts/page.html.eex
index 769e37d..579dd16 100644
--- a/priv/site/layouts/page.html.eex
+++ b/priv/site/layouts/page.html.eex
@@ -1,4 +1,4 @@
 <%= header(ctx, attrs) %>
-<main class="prose-neutral prose prose-xl dark:prose-invert">
+<main class="prose-neutral prose prose-xl dark:prose-invert" data-pagefind-body>
   <%= inner_content %>
 </main>
diff --git a/priv/site/layouts/post.html.eex b/priv/site/layouts/post.html.eex
index eecbd39..1e6a9da 100644
--- a/priv/site/layouts/post.html.eex
+++ b/priv/site/layouts/post.html.eex
@@ -1,5 +1,5 @@
 <%= header(ctx, attrs) %>
 
-<article class="prose-neutral prose prose-xl dark:prose-invert">
+<article class="prose-neutral prose prose-xl dark:prose-invert" data-pagefind-body>
   <%= inner_content %>
 </article>
diff --git a/priv/site/layouts/root.html.eex b/priv/site/layouts/root.html.eex
index 0355a68..6b834ff 100644
--- a/priv/site/layouts/root.html.eex
+++ b/priv/site/layouts/root.html.eex
@@ -1,14 +1,14 @@
 <!DOCTYPE html>
-<html class="m-4 flex flex-row justify-center">
+<html class="m-4 flex flex-row justify-center" lang="en-US">
   <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <link rel="icon" type="image/x-icon" sizes="32x32" href="/assets/img/favicon-32x32.png">
     <title><%= prefix_title("sloane.sh", attrs[:page_title]) %></title>
-    <link rel="stylesheet" href="/assets/app.css" />
+    <link rel="stylesheet" href="/assets/css/app.css" />
   </head>
-  <body class="w-full max-w-3xl bg-white text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100">
+  <body class="w-full max-w-3xl bg-white text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100 dark">
     <%= inner_content %>
-    <script defer src="/assets/app.js"></script>
+    <script defer src="/assets/js/app.js"></script>
   </body>
 </html>
diff --git a/priv/site/pages/search.md b/priv/site/pages/search.md
new file mode 100644
index 0000000..45fb6f7
--- /dev/null
+++ b/priv/site/pages/search.md
@@ -0,0 +1,13 @@
++++
+permalink = "/search"
++++
+
+<div class="mt-6" id="search"></div>
+
+<link rel="stylesheet" href="/pagefind/pagefind-ui.css" />
+<script src="/pagefind/pagefind-ui.js"></script>
+<script>
+window.addEventListener('DOMContentLoaded', () => {
+  new PagefindUI({ element: '#search', showSubResults: true });
+});
+</script>
diff --git a/priv/site/posts/2024-02-16-test-post.md b/priv/site/posts/2024-02-16-test-post.md
index c4bc5cc..361ca99 100644
--- a/priv/site/posts/2024-02-16-test-post.md
+++ b/priv/site/posts/2024-02-16-test-post.md
@@ -1,7 +1,10 @@
 +++
 title = "Test Post"
+page_title = "Test Post"
 +++
 
+# Test Post
+
 this is just a test of the posts functionality
 
 Does this work ?