Monorepo for Tangled tangled.org

nix,docs: add pagefind for search

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>

anirudh.fi 9d516aae 7cc6d7d5

verified
+220 -105
+1 -7
docs/search.html
··· 1 - <form action="https://google.com/search" role="search" aria-label="Sitewide" class="w-full"> 2 - <input type="hidden" name="q" value="+[inurl:https://docs.tangled.org]"> 3 - <label> 4 - <span style="display:none;">Search</span> 5 - <input type="text" name="q" placeholder="Search docs ..." class="w-full font-normal"> 6 - </label> 7 - </form> 1 + <div class="pagefind-search"></div>
+182 -91
docs/styles.css
··· 1 + @media (max-width: 768px) { 2 + .pagefind-ui__result-thumb { 3 + width: 0 !important; 4 + } 5 + .pagefind-ui__result-excerpt, 6 + .pagefind-ui__result-title { 7 + overflow-wrap: break-word; 8 + word-break: break-word; 9 + } 10 + .pagefind-ui__search-input, 11 + .pagefind-ui__search-clear { 12 + max-width: 100%; 13 + } 14 + .pagefind-ui__form { 15 + overflow: hidden; 16 + } 17 + } 18 + 1 19 svg { 2 - width: 16px; 3 - height: 16px; 20 + width: 16px; 21 + height: 16px; 4 22 } 5 23 6 24 :root { 7 - --syntax-alert: #d20f39; 8 - --syntax-annotation: #fe640b; 9 - --syntax-attribute: #df8e1d; 10 - --syntax-basen: #40a02b; 11 - --syntax-builtin: #1e66f5; 12 - --syntax-controlflow: #8839ef; 13 - --syntax-char: #04a5e5; 14 - --syntax-constant: #fe640b; 15 - --syntax-comment: #9ca0b0; 16 - --syntax-commentvar: #7c7f93; 17 - --syntax-documentation: #9ca0b0; 18 - --syntax-datatype: #df8e1d; 19 - --syntax-decval: #40a02b; 20 - --syntax-error: #d20f39; 21 - --syntax-extension: #4c4f69; 22 - --syntax-float: #40a02b; 23 - --syntax-function: #1e66f5; 24 - --syntax-import: #40a02b; 25 - --syntax-information: #04a5e5; 26 - --syntax-keyword: #8839ef; 27 - --syntax-operator: #179299; 28 - --syntax-other: #8839ef; 29 - --syntax-preprocessor: #ea76cb; 30 - --syntax-specialchar: #04a5e5; 31 - --syntax-specialstring: #ea76cb; 32 - --syntax-string: #40a02b; 33 - --syntax-variable: #8839ef; 34 - --syntax-verbatimstring: #40a02b; 35 - --syntax-warning: #df8e1d; 25 + --syntax-alert: #d20f39; 26 + --syntax-annotation: #fe640b; 27 + --syntax-attribute: #df8e1d; 28 + --syntax-basen: #40a02b; 29 + --syntax-builtin: #1e66f5; 30 + --syntax-controlflow: #8839ef; 31 + --syntax-char: #04a5e5; 32 + --syntax-constant: #fe640b; 33 + --syntax-comment: #9ca0b0; 34 + --syntax-commentvar: #7c7f93; 35 + --syntax-documentation: #9ca0b0; 36 + --syntax-datatype: #df8e1d; 37 + --syntax-decval: #40a02b; 38 + --syntax-error: #d20f39; 39 + --syntax-extension: #4c4f69; 40 + --syntax-float: #40a02b; 41 + --syntax-function: #1e66f5; 42 + --syntax-import: #40a02b; 43 + --syntax-information: #04a5e5; 44 + --syntax-keyword: #8839ef; 45 + --syntax-operator: #179299; 46 + --syntax-other: #8839ef; 47 + --syntax-preprocessor: #ea76cb; 48 + --syntax-specialchar: #04a5e5; 49 + --syntax-specialstring: #ea76cb; 50 + --syntax-string: #40a02b; 51 + --syntax-variable: #8839ef; 52 + --syntax-verbatimstring: #40a02b; 53 + --syntax-warning: #df8e1d; 36 54 } 37 55 38 56 @media (prefers-color-scheme: dark) { 39 - :root { 40 - --syntax-alert: #f38ba8; 41 - --syntax-annotation: #fab387; 42 - --syntax-attribute: #f9e2af; 43 - --syntax-basen: #a6e3a1; 44 - --syntax-builtin: #89b4fa; 45 - --syntax-controlflow: #cba6f7; 46 - --syntax-char: #89dceb; 47 - --syntax-constant: #fab387; 48 - --syntax-comment: #6c7086; 49 - --syntax-commentvar: #585b70; 50 - --syntax-documentation: #6c7086; 51 - --syntax-datatype: #f9e2af; 52 - --syntax-decval: #a6e3a1; 53 - --syntax-error: #f38ba8; 54 - --syntax-extension: #cdd6f4; 55 - --syntax-float: #a6e3a1; 56 - --syntax-function: #89b4fa; 57 - --syntax-import: #a6e3a1; 58 - --syntax-information: #89dceb; 59 - --syntax-keyword: #cba6f7; 60 - --syntax-operator: #94e2d5; 61 - --syntax-other: #cba6f7; 62 - --syntax-preprocessor: #f5c2e7; 63 - --syntax-specialchar: #89dceb; 64 - --syntax-specialstring: #f5c2e7; 65 - --syntax-string: #a6e3a1; 66 - --syntax-variable: #cba6f7; 67 - --syntax-verbatimstring: #a6e3a1; 68 - --syntax-warning: #f9e2af; 69 - } 57 + :root { 58 + --syntax-alert: #f38ba8; 59 + --syntax-annotation: #fab387; 60 + --syntax-attribute: #f9e2af; 61 + --syntax-basen: #a6e3a1; 62 + --syntax-builtin: #89b4fa; 63 + --syntax-controlflow: #cba6f7; 64 + --syntax-char: #89dceb; 65 + --syntax-constant: #fab387; 66 + --syntax-comment: #6c7086; 67 + --syntax-commentvar: #585b70; 68 + --syntax-documentation: #6c7086; 69 + --syntax-datatype: #f9e2af; 70 + --syntax-decval: #a6e3a1; 71 + --syntax-error: #f38ba8; 72 + --syntax-extension: #cdd6f4; 73 + --syntax-float: #a6e3a1; 74 + --syntax-function: #89b4fa; 75 + --syntax-import: #a6e3a1; 76 + --syntax-information: #89dceb; 77 + --syntax-keyword: #cba6f7; 78 + --syntax-operator: #94e2d5; 79 + --syntax-other: #cba6f7; 80 + --syntax-preprocessor: #f5c2e7; 81 + --syntax-specialchar: #89dceb; 82 + --syntax-specialstring: #f5c2e7; 83 + --syntax-string: #a6e3a1; 84 + --syntax-variable: #cba6f7; 85 + --syntax-verbatimstring: #a6e3a1; 86 + --syntax-warning: #f9e2af; 87 + } 70 88 } 71 89 72 90 /* pandoc syntax highlighting classes */ 73 - code span.al { color: var(--syntax-alert); font-weight: bold; } /* alert */ 74 - code span.an { color: var(--syntax-annotation); font-weight: bold; font-style: italic; } /* annotation */ 75 - code span.at { color: var(--syntax-attribute); } /* attribute */ 76 - code span.bn { color: var(--syntax-basen); } /* basen */ 77 - code span.bu { color: var(--syntax-builtin); } /* builtin */ 78 - code span.cf { color: var(--syntax-controlflow); font-weight: bold; } /* controlflow */ 79 - code span.ch { color: var(--syntax-char); } /* char */ 80 - code span.cn { color: var(--syntax-constant); } /* constant */ 81 - code span.co { color: var(--syntax-comment); font-style: italic; } /* comment */ 82 - code span.cv { color: var(--syntax-commentvar); font-weight: bold; font-style: italic; } /* commentvar */ 83 - code span.do { color: var(--syntax-documentation); font-style: italic; } /* documentation */ 84 - code span.dt { color: var(--syntax-datatype); } /* datatype */ 85 - code span.dv { color: var(--syntax-decval); } /* decval */ 86 - code span.er { color: var(--syntax-error); font-weight: bold; } /* error */ 87 - code span.ex { color: var(--syntax-extension); } /* extension */ 88 - code span.fl { color: var(--syntax-float); } /* float */ 89 - code span.fu { color: var(--syntax-function); } /* function */ 90 - code span.im { color: var(--syntax-import); font-weight: bold; } /* import */ 91 - code span.in { color: var(--syntax-information); font-weight: bold; font-style: italic; } /* information */ 92 - code span.kw { color: var(--syntax-keyword); font-weight: bold; } /* keyword */ 93 - code span.op { color: var(--syntax-operator); } /* operator */ 94 - code span.ot { color: var(--syntax-other); } /* other */ 95 - code span.pp { color: var(--syntax-preprocessor); } /* preprocessor */ 96 - code span.sc { color: var(--syntax-specialchar); } /* specialchar */ 97 - code span.ss { color: var(--syntax-specialstring); } /* specialstring */ 98 - code span.st { color: var(--syntax-string); } /* string */ 99 - code span.va { color: var(--syntax-variable); } /* variable */ 100 - code span.vs { color: var(--syntax-verbatimstring); } /* verbatimstring */ 101 - code span.wa { color: var(--syntax-warning); font-weight: bold; font-style: italic; } /* warning */ 91 + code span.al { 92 + color: var(--syntax-alert); 93 + font-weight: bold; 94 + } /* alert */ 95 + code span.an { 96 + color: var(--syntax-annotation); 97 + font-weight: bold; 98 + font-style: italic; 99 + } /* annotation */ 100 + code span.at { 101 + color: var(--syntax-attribute); 102 + } /* attribute */ 103 + code span.bn { 104 + color: var(--syntax-basen); 105 + } /* basen */ 106 + code span.bu { 107 + color: var(--syntax-builtin); 108 + } /* builtin */ 109 + code span.cf { 110 + color: var(--syntax-controlflow); 111 + font-weight: bold; 112 + } /* controlflow */ 113 + code span.ch { 114 + color: var(--syntax-char); 115 + } /* char */ 116 + code span.cn { 117 + color: var(--syntax-constant); 118 + } /* constant */ 119 + code span.co { 120 + color: var(--syntax-comment); 121 + font-style: italic; 122 + } /* comment */ 123 + code span.cv { 124 + color: var(--syntax-commentvar); 125 + font-weight: bold; 126 + font-style: italic; 127 + } /* commentvar */ 128 + code span.do { 129 + color: var(--syntax-documentation); 130 + font-style: italic; 131 + } /* documentation */ 132 + code span.dt { 133 + color: var(--syntax-datatype); 134 + } /* datatype */ 135 + code span.dv { 136 + color: var(--syntax-decval); 137 + } /* decval */ 138 + code span.er { 139 + color: var(--syntax-error); 140 + font-weight: bold; 141 + } /* error */ 142 + code span.ex { 143 + color: var(--syntax-extension); 144 + } /* extension */ 145 + code span.fl { 146 + color: var(--syntax-float); 147 + } /* float */ 148 + code span.fu { 149 + color: var(--syntax-function); 150 + } /* function */ 151 + code span.im { 152 + color: var(--syntax-import); 153 + font-weight: bold; 154 + } /* import */ 155 + code span.in { 156 + color: var(--syntax-information); 157 + font-weight: bold; 158 + font-style: italic; 159 + } /* information */ 160 + code span.kw { 161 + color: var(--syntax-keyword); 162 + font-weight: bold; 163 + } /* keyword */ 164 + code span.op { 165 + color: var(--syntax-operator); 166 + } /* operator */ 167 + code span.ot { 168 + color: var(--syntax-other); 169 + } /* other */ 170 + code span.pp { 171 + color: var(--syntax-preprocessor); 172 + } /* preprocessor */ 173 + code span.sc { 174 + color: var(--syntax-specialchar); 175 + } /* specialchar */ 176 + code span.ss { 177 + color: var(--syntax-specialstring); 178 + } /* specialstring */ 179 + code span.st { 180 + color: var(--syntax-string); 181 + } /* string */ 182 + code span.va { 183 + color: var(--syntax-variable); 184 + } /* variable */ 185 + code span.vs { 186 + color: var(--syntax-verbatimstring); 187 + } /* verbatimstring */ 188 + code span.wa { 189 + color: var(--syntax-warning); 190 + font-weight: bold; 191 + font-style: italic; 192 + } /* warning */
+22 -7
docs/template.html
··· 34 34 $header-includes$ 35 35 $endfor$ 36 36 37 - <link rel="preload" href="/static/fonts/InterVariable.woff2" as="font" type="font/woff2" crossorigin /> 38 - <link rel="icon" href="/static/logos/dolly.ico" sizes="48x48"/> 39 - <link rel="icon" href="/static/logos/dolly.svg" sizes="any" type="image/svg+xml"/> 40 - <link rel="apple-touch-icon" href="/static/logos/dolly.png"/> 37 + <link href="$root$pagefind/pagefind-ui.css" rel="stylesheet"> 38 + <script src="$root$pagefind/pagefind-ui.js"></script> 39 + <script> 40 + window.addEventListener("DOMContentLoaded", () => { 41 + document.querySelectorAll(".pagefind-search").forEach((el) => { 42 + new PagefindUI({ 43 + element: el, 44 + showSubResults: true, 45 + resetStyles: false, 46 + }); 47 + }); 48 + }); 49 + </script> 50 + <link rel="preload" href="$root$static/fonts/InterVariable.woff2" as="font" type="font/woff2" crossorigin /> 51 + <link rel="icon" href="$root$static/logos/dolly.ico" sizes="48x48"/> 52 + <link rel="icon" href="$root$static/logos/dolly.svg" sizes="any" type="image/svg+xml"/> 53 + <link rel="apple-touch-icon" href="$root$static/logos/dolly.png"/> 41 54 42 55 </head> 43 - <body class="bg-white dark:bg-gray-900 flex flex-col min-h-svh"> 56 + <body class="bg-white dark:bg-gray-900 flex flex-col min-h-svh"$if(single-page)$ data-pagefind-ignore$endif$> 44 57 $for(include-before)$ 45 58 $include-before$ 46 59 $endfor$ 47 60 48 61 $if(toc)$ 49 62 <!-- mobile TOC trigger --> 50 - <div class="md:hidden px-6 py-4 border-b border-gray-200 dark:border-gray-700"> 63 + <div data-pagefind-ignore class="md:hidden px-6 py-4 border-b border-gray-200 dark:border-gray-700"> 51 64 <button 52 65 type="button" 53 66 popovertarget="mobile-toc-popover" ··· 62 75 <div 63 76 id="mobile-toc-popover" 64 77 popover 78 + data-pagefind-ignore 65 79 class="mobile-toc-popover 66 80 bg-gray-50 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 67 - h-full overflow-y-auto shadow-sm 81 + h-full overflow-x-hidden overflow-y-auto shadow-sm 68 82 px-6 py-4 fixed inset-x-0 top-0 w-fit max-w-4/5 m-0" 69 83 > 70 84 <div class="flex flex-col min-h-full"> ··· 89 103 <nav 90 104 id="$idprefix$TOC" 91 105 role="doc-toc" 106 + data-pagefind-ignore 92 107 class="hidden md:flex md:flex-col gap-4 fixed left-0 top-0 w-80 h-screen 93 108 bg-gray-50 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 94 109 p-4 z-50 overflow-y-auto">
+11
flake.nix
··· 100 100 appview = self.callPackage ./nix/pkgs/appview.nix {}; 101 101 docs = self.callPackage ./nix/pkgs/docs.nix { 102 102 inherit inter-fonts-src ibm-plex-mono-src lucide-src; 103 + inherit (pkgs) pagefind; 103 104 }; 104 105 spindle = self.callPackage ./nix/pkgs/spindle.nix {}; 105 106 knot-unwrapped = self.callPackage ./nix/pkgs/knot-unwrapped.nix {}; ··· 256 257 watch-tailwind = { 257 258 type = "app"; 258 259 program = ''${tailwind-watcher}/bin/run''; 260 + }; 261 + serve-docs = { 262 + type = "app"; 263 + program = toString (pkgs.writeShellScript "serve-docs" '' 264 + echo "building docs..." 265 + docsOut=$(nix build --no-link --print-out-paths .#docs) 266 + echo "serving docs at http://localhost:1414" 267 + cd "$docsOut" 268 + exec ${pkgs.python3}/bin/python3 -m http.server 1414 269 + ''); 259 270 }; 260 271 vm = let 261 272 guestSystem =
+4
nix/pkgs/docs.nix
··· 1 1 { 2 2 pandoc, 3 + pagefind, 3 4 tailwindcss, 4 5 runCommandLocal, 5 6 inter-fonts-src, ··· 59 60 60 61 # styles 61 62 cd ${src} && ${tailwindcss}/bin/tailwindcss -i input.css -o $out/stylesheet.css 63 + 64 + # search index 65 + ${pagefind}/bin/pagefind --site $out --output-path $out/pagefind 62 66 ''